您的位置:首页 > 编程语言 > Java开发

使用Spring管理事务

2016-08-02 09:41 393 查看

使用Spring管理事务

1. 理解事务管理

任何处理数据的系统都必须保护数据的完整性

ACID(原子性、一致性、隔离性、持久性)

- 原子性

在任何事物中都可能在数据上执行多个操作。这些操作必须全部都成功或提交,或者如果有任何一个操作失败,则所有操作都应该被抛弃

- 一致性

为了让一个系统保持一致,一个活动事务结束之后底层数据库必须处于一致状态

- 隔离性

隔离性定义了如何保护未提交数据免受其他并发事务的影响

- 持久性

当接受到一个成功的提交消息时,系统就具有了持久性,从而可以确认所做的更改已经反映到系统中,而此后可以处理任何可能发生的系统故障

使用JDBC API定义事务边界

//注册驱动
DriverManager.registerDriver(new Driver());
//获取连接
connection=DriverManager.getConnection("jdbc:h2:tcp://localhost/~/test", "sa", "");
//设置不自动提交
connection.setAutoCommit(false);
//获取Statement
Statement statement=connection.createStatement();
//执行SQL语句 一方减少余额 一方增加余额
statement.executeUpdate("update account set balance = balance - " + amount + " where id = " + sourceAccountId);
statement.executeUpdate("update account set balance = balance + " + amount + " where id = " + targetAccountId);
//提交事务
connection.commit();


2. Spring的事务抽象模型

每种数据访问技术都有其事务机制,Spring的事务抽象模型基于PlatformTransactionManager接口

在Spring容器中配置PlatformTransactionManager Bean

@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource=new DriverManagerDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:tcp://localhost/~/test");
dataSource.setUsername("sa");
dataSource.setPassword("");
return dataSource;
}
@Bean
public PlatformTransactionManager transactionManager(){
DataSourceTransactionManager transactionManager=new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource());
return transactionManager;
}


本体事务和全局事务

本地事务意味着应用程序使用单一数据库,且事务仅控制在该单一数据库上执行的DML操作

全局事务则意味着分布式事务管理。

Spring的抽象事务模型的优点

能够在相同的应用程序中使用不同的数据访问技术。可以同时使用声明式和编程式事务模型

非常方便更改应用程序的数据访问技术

很容易从本地事务切换到全局事务

3. 使用Spring进行声明式事务管理

try{
begin transaction
execute transactional code block
commit transaction
}catch(Exception e){
handle exception
rollback transaction
}finally{
do resource clean up
}


在Spring中启用声明式事务管理

//使用@EnableTransactionManagement注解激活基于注解的声明式事务管理
@EnableTransactionManagement
@Configuration
public class Config {
...
}

@Transactional
public void transferMoney(long sourceAccountId, long targetAccountId, double amount) {
//获取连接
Connection connection= DataSourceUtils.getConnection(dataSource);

//获取Statement
Statement statement= null;
try {
statement = connection.createStatement();
//执行SQL语句 一方减少余额 一方增加余额
statement.executeUpdate("update account set balance = balance - " + amount + " where id = " + sourceAccountId);
statement.executeUpdate("update account set balance = balance + " + amount + " where id = " + targetAccountId);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally {
DataSourceUtils.releaseConnection(connection,dataSource);
}

}


使用
<tx:advice>
进行声明式事务管理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <tx:advice id="FileName_txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor advice-ref="FileName_txAdvice" pointcut="bean(accountService)"/>
</aop:config>
</beans>


4. 使用Spring进行编程式事务管理

使用TransactionTemplate

transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
...
}
});


使用PlatformTransactionManager

//使用PlatformTransaction创建一个新的TransactionDefinition对象,获取TransactionStatus
TransactionDefinition definition=new DefaultTransactionDefinition();
TransactionStatus status=transactionManager.getTransaction(definition);

try {
...
transactionManager.commit(status);

}catch (Exception e){
transactionManager.rollback(status);
throw new RuntimeException(e);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: