myBatis系列之七:事务管理
myBatis系列之一:搭建开发环境
myBatis系列之二:以接口方式交互数据
myBatis系列之三:增删改查
myBatis系列之四:关联数据的查询
myBatis系列之五:与Spring3集成
myBatis系列之六:与SpringMVC集成
1.myBatis单独使用时,使用SqlSession来处理事务:
public class MyBatisTxTest { private static SqlSessionFactory sqlSessionFactory; private static Reader reader; @BeforeClass public static void setUpBeforeClass() throws Exception { try { reader = Resources.getResourceAsReader("Configuration.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } finally { if (reader != null) { reader.close(); } } } @Test public void updateUserTxTest() { SqlSession session = sqlSessionFactory.openSession(false); // 打开会话,事务开始 try { IUserMapper mapper = session.getMapper(IUserMapper.class); User user = new User(9, "Test transaction"); int affectedCount = mapper.updateUser(user); // 因后面的异常而未执行commit语句 User user = new User(10, "Test transaction continuously"); int affectedCount2 = mapper.updateUser(user2); // 因后面的异常而未执行commit语句 int i = 2 / 0; // 触发运行时异常 session.commit(); // 提交会话,即事务提交 } finally { session.close(); // 关闭会话,释放资源 } } }
2.和Spring集成后,使用Spring的事务管理:
a.@Transactional方式:
在类路径下创建beans-da-tx.xml文件,在beans-da.xml(系列五)的基础上加入事务配置:
<!-- 事务管理器 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 事务注解驱动,标注@Transactional的类和方法将具有事务性 --> <tx:annotation-driven transaction-manager="txManager" /> <bean id="userService" class="com.john.hbatis.service.UserService" />
服务类:
@Service("userService") public class UserService { @Autowired IUserMapper mapper; public int batchUpdateUsersWhenException() { // 非事务性 User user = new User(9, "Before exception"); int affectedCount = mapper.updateUser(user); // 执行成功 User user2 = new User(10, "After exception"); int i = 1 / 0; // 抛出运行时异常 int affectedCount2 = mapper.updateUser(user2); // 未执行 if (affectedCount == 1 && affectedCount2 == 1) { return 1; } return 0; } @Transactional public int txUpdateUsersWhenException() { // 事务性 User user = new User(9, "Before exception"); int affectedCount = mapper.updateUser(user); // 因后面的异常而回滚 User user2 = new User(10, "After exception"); int i = 1 / 0; // 抛出运行时异常,事务回滚 int affectedCount2 = mapper.updateUser(user2); // 未执行 if (affectedCount == 1 && affectedCount2 == 1) { return 1; } return 0; } }
在测试类中加入:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:beans-da-tx.xml" }) public class SpringIntegrateTxTest { @Resource UserService userService; @Test public void updateUsersExceptionTest() { userService.batchUpdateUsersWhenException(); } @Test public void txUpdateUsersExceptionTest() { userService.txUpdateUsersWhenException(); } }
b.TransactionTemplate方式
在beans-da-tx.xml中添加:
<bean id="txTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <constructor-arg type="org.springframework.transaction.PlatformTransactionManager" ref="transactionManager" /> </bean>
在UserService类加入:
@Autowired(required = false) TransactionTemplate txTemplate; public int txUpdateUsersWhenExceptionViaTxTemplate() { int retVal = txTemplate.execute(new TransactionCallback<Integer>() { @Override public Integer doInTransaction(TransactionStatus status) { // 事务操作 User user = new User(9, "Before exception"); int affectedCount = mapper.updateUser(user); // 因后面的异常而回滚 User user2 = new User(10, "After exception"); int i = 1 / 0; // 抛出运行时异常并回滚 int affectedCount2 = mapper.updateUser(user2); // 未执行 if (affectedCount == 1 && affectedCount2 == 1) { return 1; } return 0; } }); return retVal; }
在SpringIntegrateTxTest类中加入:
@Test public void updateUsersWhenExceptionViaTxTemplateTest() { userService.txUpdateUsersWhenExceptionViaTxTemplate(); // }
注:不可catchException或RuntimeException而不抛出:
@Transactional public int txUpdateUsersWhenExceptionAndCatch() { // 事务性操作,但是外围框架捕获不到异常,认为执行正确而提交。 try { User user = new User(9, "Before exception"); int affectedCount = mapper.updateUser(user); // 执行成功 User user2 = new User(10, "After exception"); int i = 1 / 0; // 抛出运行时异常 int affectedCount2 = mapper.updateUser(user2); // 未执行 if (affectedCount == 1 && affectedCount2 == 1) { return 1; } } catch (Exception e) { // 所有异常被捕获而未抛出 e.printStackTrace(); } return 0; }
相关推荐
spurity 2020-11-10
LeeLuffy 2020-10-16
DriveCar 2020-09-07
xkorey 2020-09-14
zjuwangleicn 2020-09-04
dongtiandeyu 2020-08-18
Langeldep 2020-08-16
gamestart0 2020-08-15
loviezhang 2020-08-08
gaozhennan 2020-08-03
mcvsyy 2020-08-02
wenjieyatou 2020-07-30
happinessaflower 2020-07-29
花落花开春去秋来 2020-07-29
solarspot 2020-07-28
powrexly 2020-07-20
牧场SZShepherd 2020-07-20
qingjiuquan 2020-07-18