博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring 事务管理
阅读量:3964 次
发布时间:2019-05-24

本文共 11393 字,大约阅读时间需要 37 分钟。

Spring 事务管理

what?

  • 在操作数据库设计到事务管理的问题,为此Spring提供专门的API用于处理事务。
  • jar包spring-tx-4.3.6RELEASE

核心接口

  • PlatformTransactionManager
  • TransactionDefinition
  • TransactionStatus

PlatformTransactionManager

在这里插入图片描述

TransactionDefinition

  • 该接口是事务定义(描述)的对象,该对象定义了事务的相关规则,并且提供获取事务相关信息的方法。
  • String getName():获取事务的对象名称
  • int getlsolationLevel():获取事务的隔离等级
  • int getPropagationBehavior():获取事务的传播行为
  • int getTimeout:获取事务的超时事件
  • boolean isReadOnly():获取事务是否可读
  • 事务的传播行为:指的是在一个方法中,不同操作前后使用的事务,
    在这里插入图片描述

TransactionStatus

  • 该接口是事务的状态,描述某一时间点上事务的信息。
  • void flush():刷新事务
  • boolean hasSavepoint():获取是否存在保存点
  • boolean inCompleted():获取事务是否完成
  • boolean isNewTransaction:获取是否是新事物
  • boolean isRollbackOnly():获取是否回滚
  • void setRollbackOnly():设置事务回滚。

事务管理的方式

编程式事务管理

  • 通过编写代码实现事务管理,包括定义事务的开始,正常执行后的事务提交和异常时的事务回滚。
package cn.itcast.itcaststore.utils;import java.sql.Connection;import java.sql.SQLException;import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource;/** * 数据源工具 */public class DataSourceUtils {	private static DataSource dataSource = new ComboPooledDataSource();	private static ThreadLocal
tl = new ThreadLocal
(); public static DataSource getDataSource() { return dataSource; } /** * 当DBUtils需要手动控制事务时,调用该方法获得一个连接 * @return * @throws SQLException */ public static Connection getConnection() throws SQLException { Connection con = tl.get(); if (con == null) { con = dataSource.getConnection(); tl.set(con); } return con; } /** * 开启事务 * @throws SQLException */ public static void startTransaction() throws SQLException { Connection con = getConnection(); if (con != null) con.setAutoCommit(false); } /** * 从ThreadLocal中释放并且关闭Connection,并结束事务 * @throws SQLException */ public static void releaseAndCloseConnection() throws SQLException { Connection con = getConnection(); if (con != null) { con.commit(); tl.remove(); con.close(); } } /** * 事务回滚 * @throws SQLException */ public static void rollback() throws SQLException { Connection con = getConnection(); if (con != null) { con.rollback(); } }}

声明式事务管理

透过AOP技术实现事务管理,将事务作为一个“切面”单独编写,在将这个植入到需要的业务类中,

有注解式和xml文件配置式。

基于XML声明式事务

  • 在spring中提供tx命名空间类配置事务,通过tx:advice配置事务的通知,在通过aop的配置,让spring自动代理,
    在这里插入图片描述
    在这里插入图片描述

代码

Account

package com.yzb.chatper05;public class Account {    private Integer id;    private String username;    private Double balance;    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }    public Double getBalance() {        return balance;    }    public void setBalance(Double balance) {        this.balance = balance;    }    @Override    public String toString() {        return "Account{" +                "id=" + id +                ", username='" + username + '\'' +                ", balance=" + balance +                '}';    }}

AccountDao

package com.yzb.chatper05;import java.util.List;public interface AccountDao {    //添加账户    public int addAccount(Account account);//    更改用户    public  int updateAccount(Account account);    //删除用户    public int deleteAccount(int id);    //通过id查询    public Account findAccountById(int id);    //查询所有    public List
findAllAccount(); //转账 public void transfer(String outUser,String inUser ,Double money);}

AccountDaoImpl

package com.yzb.chatper05;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;import java.util.List;public class AccountDaoImpl implements AccountDao {    //声明JdbcTemplate属性以及setter方法    private JdbcTemplate jdbcTemplate;    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {        this.jdbcTemplate = jdbcTemplate;    }    //添加用户    @Override    public int addAccount(Account account) {        //定义SQL        String sql = "insert into account(username,balance) value(?,?)";        //定义一个数组存储sql中的参数        Object[] obj = {account.getUsername(),account.getBalance()};        //执行添加操作,返回的是受sql语句影响的记录条数        int update = jdbcTemplate.update(sql, obj);        return update;    }    //更改用户    @Override    public int updateAccount(Account account) {        //定义SQL        String sql = "update account set username=?,balance=? where id=?";        //定义一个数组存储sql中的参数        Object[] obj = {account.getUsername(),account.getBalance(),account.getId()};        //执行更改操作,返回的是受sql语句影响的记录条数        int update = jdbcTemplate.update(sql, obj);        return update;    }    //删除用户    @Override    public int deleteAccount(int id) {    //定义sql        String sql = "delete from account where id=?";        //执行更改操作,返回的是受sql语句影响的记录条数        int update = jdbcTemplate.update(sql, id);        return update;    }    //通过ID查询账户    @Override    public Account findAccountById(int id) {        //定义sql语句        String sql ="select * from account where id=?";        //创建一个新的BeanPropertyRowMapper对象        RowMapper
rowMapper = new BeanPropertyRowMapper
(Account.class); //将id保定到sql语句中,通过RowMapper返回一个Object类型的单行记录 Account account = this.jdbcTemplate.queryForObject(sql, rowMapper, id); return account; } //查询所有的账户信息 @Override public List
findAllAccount() { //定义sql语句 String sql ="select * from account"; //创建一个新的BeanPropertyRowMapper对象 RowMapper
rowMapper = new BeanPropertyRowMapper
(Account.class); //执行静态的sql语句查询,通过RowMapper返回结果 List
query = this.jdbcTemplate.query(sql, rowMapper); return query; }/** 转账* outUser:汇款人* inUser:收款人* money:转账金额* */ @Override public void transfer(String outUser, String inUser, Double money) { //收款时,首款用户的余额=现有余额 + 收款余额 this.jdbcTemplate.update("update account set balance = balance + ?" +"where username=?" ,money,inUser); //模拟系统运行时的突发性问题 int i = 1/0; //汇款时,汇款用户的余额= 现有金额 - 汇款金额 this.jdbcTemplate.update("update account set balance = balance - ?" +"where username=?" ,money,outUser); }}

applicationContext.xml

Test

package com.yzb.chatper05;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {    public static void main(String[] args) {        String path = "com/yzb/chatper05/applicationContext.xml";        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);        AccountDao accountDao = (AccountDao) applicationContext.getBean("accountDao");        accountDao.transfer("tom","jack",100.0);        System.out.println("转账成功");    }}

基于Annotation方式的声明

  • 在spring容器中,注册事务注解驱动,
  • 配置事务管理器驱动
    <tx:annotation-driven transaction-manager=“transactionManager”></tx:annotation-driven>
  • 注解@Transaction,将这个注解加载Bean类上面,则事务的设置对Bean类的所有的方法都起作用,如果将注解添加在Bean类的某个方法中,则表示事务的设置只对该方法有效。
    在这里插入图片描述

代码

在xml的代码上面进行的更改

AccountDao

package com.yzb.chatper05;import java.util.List;public interface AccountDao {    //添加账户    public int addAccount(Account account);//    更改用户    public  int updateAccount(Account account);    //删除用户    public int deleteAccount(int id);    //通过id查询    public Account findAccountById(int id);    //查询所有    public List
findAllAccount(); //转账 public void transfer(String outUser,String inUser ,Double money);}

AccountDaoImpl

package com.yzb.chatper05;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;import org.springframework.transaction.annotation.Isolation;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import java.util.List;public class AccountDaoImpl implements AccountDao {    //声明JdbcTemplate属性以及setter方法    private JdbcTemplate jdbcTemplate;    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {        this.jdbcTemplate = jdbcTemplate;    }    //添加用户    @Override    public int addAccount(Account account) {        //定义SQL        String sql = "insert into account(username,balance) value(?,?)";        //定义一个数组存储sql中的参数        Object[] obj = {account.getUsername(),account.getBalance()};        //执行添加操作,返回的是受sql语句影响的记录条数        int update = jdbcTemplate.update(sql, obj);        return update;    }    //更改用户    @Override    public int updateAccount(Account account) {        //定义SQL        String sql = "update account set username=?,balance=? where id=?";        //定义一个数组存储sql中的参数        Object[] obj = {account.getUsername(),account.getBalance(),account.getId()};        //执行更改操作,返回的是受sql语句影响的记录条数        int update = jdbcTemplate.update(sql, obj);        return update;    }    //删除用户    @Override    public int deleteAccount(int id) {    //定义sql        String sql = "delete from account where id=?";        //执行更改操作,返回的是受sql语句影响的记录条数        int update = jdbcTemplate.update(sql, id);        return update;    }    //通过ID查询账户    @Override    public Account findAccountById(int id) {        //定义sql语句        String sql ="select * from account where id=?";        //创建一个新的BeanPropertyRowMapper对象        RowMapper
rowMapper = new BeanPropertyRowMapper
(Account.class); //将id保定到sql语句中,通过RowMapper返回一个Object类型的单行记录 Account account = this.jdbcTemplate.queryForObject(sql, rowMapper, id); return account; } //查询所有的账户信息 @Override public List
findAllAccount() { //定义sql语句 String sql ="select * from account"; //创建一个新的BeanPropertyRowMapper对象 RowMapper
rowMapper = new BeanPropertyRowMapper
(Account.class); //执行静态的sql语句查询,通过RowMapper返回结果 List
query = this.jdbcTemplate.query(sql, rowMapper); return query; }/** 转账* outUser:汇款人* inUser:收款人* money:转账金额* */ @Override @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,readOnly = false) public void transfer(String outUser, String inUser, Double money) { //收款时,首款用户的余额=现有余额 + 收款余额 this.jdbcTemplate.update("update account set balance = balance + ?" +"where username=?" ,money,inUser); //模拟系统运行时的突发性问题 // int i = 1/0; //汇款时,汇款用户的余额= 现有金额 - 汇款金额 this.jdbcTemplate.update("update account set balance = balance - ?" +"where username=?" ,money,outUser); }}

applicationContext-annotation.xml

Test1

package com.yzb.chatper05;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test1 {    public static void main(String[] args) {        String path = "com/yzb/chatper05/applicationContext-annotation.xml";        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);        AccountDao accountDao = (AccountDao) applicationContext.getBean("accountDao");        accountDao.transfer("tom","jack",100.0);        System.out.println("转账成功");    }}

转载地址:http://dzwki.baihongyu.com/

你可能感兴趣的文章
ksh 控制键
查看>>
ksh 动态命令
查看>>
ksh 多进程
查看>>
ksh 命令分隔符
查看>>
Linux 精萃
查看>>
sed 精萃
查看>>
awk 精萃
查看>>
awk 简介
查看>>
awk 调用方式
查看>>
awk 注释
查看>>
awk 命令分隔符
查看>>
awk 变量
查看>>
awk 数组
查看>>
如何写出高效的SQL
查看>>
awk 运算符
查看>>
awk 控制结构
查看>>
awk 格式化输出
查看>>
awk 正则表达式
查看>>
awk 函数
查看>>
awk 向命令传递参数
查看>>