本帖最后由 大蓝鲸小蟀锅 于 2017-12-27 15:09 编辑
Spring 事务管理的总结和入门案例演示Spring事务管理高层抽象主要包括3个接口1.PlatformTransactionManager 事务管理器 2.TransactionDefinition 事务定义信息(隔离、传播、超时、只读) 3.TransactionStatus 事务具体运行状态 事务管理器PlatformTransactionManage Spring为不同的持久化框架提供了不同PlatformTransactionManager接口实现
事务隔离级别(种)如下: 脏读:一个事务读取了另个事务改写但还未提交的数据,如果这些数据被回滚,则读到的数据是无效的。 不可重复读:在同一事务中,多次读取同一数据返回的结果有所不同。换句话说就是,后续读取可以读到另一事务已提交的更新数据。相反,“可重复读”在同一事务中多次读取数据时,能够保证所读数据一样,也就是,后续读取不能读到另一事务已提交的更新数据。 幻读:一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了。再后来的查询中,第一个事务就会发现有些原来没有的记录。 事务传播行为事务传播行为用于解决两个被事务管理的方法互相调用问题 事务传播行为(七种)如下:
NESTED 嵌套事务示例如下: Connection conn = null; try { conn.setAutoCommit(false); Statement stmt = conn.createStatement(); stmt.executeUpdate("update person set name='888' where id=1"); Savepoint savepoint = conn.setSavepoint(); try{ conn.createStatement().executeUpdate("update person set name='222' where sid=2"); }catch(Exception ex){ conn.rollback(savepoint); } stmt.executeUpdate("delete from person where id=9"); conn.commit(); stmt.close(); } catch (Exception e) { conn.rollback(); }finally{ try { if(null!=conn && !conn.isClosed()) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } |
Spring 事务管理Spring 支持两种方式事务管理 编程式的事务管理 在实际应用中很少使用 通过TransactionTemplate手动管理事务 使用XML配置声明式事务 开发中推荐使用(代码侵入性最小) Spring的声明式事务是通过AOP实现的
下面是代码<转账>案例演示:1. 转账案例的环境准备 创建web工程 导入jar包 在src目录编写配置 applicationContext.xml log4j.properties jdbc.properties |
2. 编写DAO注入 注入JdbcTemplate public class AccountDAO extends JdbcDaoSupport{ public void outMoney(String account, double money) { this.getJdbcTemplate().update( "update account set money = money - ? where name = ?", money,account); } public void inMoney(String account, double money) { this.getJdbcTemplate().update( "update account set money = money + ? where name = ?", money,account); } } |
编写Service注入DAO public class AccountService { private AccountDAO accountDAO; // 转账的业务操作 public void transfer() { // aaa 向 bbb 转账 200元 accountDAO.outMoney("aaa", 200); int d = 1 / 0; accountDAO.inMoney("bbb", 200); } public void setAccountDAO(AccountDAO accountDAO) { this.accountDAO = accountDAO; } | 配置applicationContext.xml <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <!-- ${key} 可以读取properties文件中配置 key对应value --> <property name="driverClass" value="${jdbc.driver}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="accountService" class="cn.itcast.service.AccountService"> <property name="accountDAO" ref="accountDAO"></property> </bean> <bean id="accountDAO" class="cn.itcast.dao.AccountDAO"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> | 编写测试用例 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext.xml") public class SpringTest { @Autowired private AccountService accountService; @Test public void demo() { accountService.transfer(); } } | 使用XML配置声明式事务 基于tx/aop
| | 使用XML配置声明式事务 基于tx/aop 修改测试用例 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext.xml") public class SpringTest { @Autowired private AccountService accountService; @Test public void demo() { accountService.transfer(); } } | 使用注解配置声明式事务 使用@Transactional注解 修改AccountService @Transactional public class AccountService { private AccountDAO accountDAO; // 转账的业务操作 public void transfer() { // aaa 向 bbb 转账 200元 accountDAO.outMoney("aaa", 200); // int d = 1 / 0; accountDAO.inMoney("bbb", 200); } public void setAccountDAO(AccountDAO accountDAO) { this.accountDAO = accountDAO; } } | 使用注解配置声明式事务 修改applicationContext.xml <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <!-- ${key} 可以读取properties文件中配置 key对应value --> <property name="driverClass" value="${jdbc.driver}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> ... <tx:annotation-driven/> |
|