首页
IT
登录
6mi
u
盘
搜
搜 索
IT
myBatis:事务管理
myBatis:事务管理
xiaoxiao
2021-03-26
24
1. myBatis单独使用时,使用
SqlSession
来处理事务
:
Java代码
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(系列五)的基础上加入事务配置:
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"
/>
服务类:
Java代码
@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
;
}
}
在测试类中加入:
Java代码
@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中添加:
Xml代码
<
bean
id
=
"txTemplate"
class
=
"org.springframework.transaction.support.TransactionTemplate"
>
<
constructor-arg
type
=
"org.springframework.transaction.PlatformTransactionManager"
ref
=
"transactionManager"
/>
</
bean
>
在UserService类加入:
Java代码
@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类中加入:
Java代码
@Test
public
void
updateUsersWhenExceptionViaTxTemplateTest() {
userService.txUpdateUsersWhenExceptionViaTxTemplate();
//
}
注:
不可
catch Exception
或
RuntimeException
而不抛出
:
Java代码
@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
;
}
转载请注明原文地址: https://ju.6miu.com/read-662878.html
技术
最新回复
(
0
)