事务: 保障数据操作的一致性、完整性 等等
传播性 (六种 传播性)
隔离级 (四种 隔离级)
ACID : 指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离 性(Isolation)、持久性(Durability)。一个支持事务(Transaction)的数据库,必须要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易方的要求。
产生原因:
Spring 为了了解各个技术的事务方式的 不一致,推出了事务的管理,总而简化管理和维护。
优点:
1、为复杂的事务,Api提供了一致的编程模型。
2、支持声明式的事务管理
3、支持Spring 的各种数据访问抽象
Spring 实现 及步骤
-
定义资源 DataSource
-
定义事务管理器 AOP
-
定义事务通知 ↓
-
定义事务切入点和通知
-
织入事务通知到目标对象
事务实现 准备工作
1、引入 tx 支持
2、配置数据源 以及 注入
<bean id="userDao" class="com.kgc.user.dao.UserDaoImpl" >
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 数据源连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver">
</property>
<property name="url" value="jdbc:mysql://localhost/kgc">
</property>
<property name="username" value="root"></property>
<property name="password" value="ok"></property>
</bean>
HelloWorld 具体实现 (方法一)
1、配置事务管理器
<!-- 1、配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 配置数据源 -->
<property name="DataSource" ref="dataSource"></property>
</bean>
2、配置事务管理的策略
<!-- 2、配置事务管理的策略 -->
<tx:advice id="txManager" transaction-manager="transactionManager">
<tx:attributes>
<!-- 配置一些事务属性 -->
<tx:method name="add*" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="get*" read-only="true" />
<tx:method name="*" isolation="SERIALIZABLE"></tx:method>
</tx:attributes>
</tx:advice>
3、配置事务的AOP
<!-- 3.1、配置事务的AOP -->
<aop:config>
<!-- 注意:事务应该配置在逻辑层,不应该放在数据层 -->
<aop:pointcut expression="execution(* com.kgc.user2.dao.*.*(..))" id="myPointCut"/>
<aop:advisor advice-ref="txManager" pointcut-ref="myPointCut"/>
</aop:config>
Spring 事务管理深入
Spring 的事务管理通过AOP 实现 : 见上图
我们可以通过修改配置,选择不同的事务策略
属性 默认值 描述
name 与事务属性关联的方法名
* Propagation REQUIRED 事务传播行为
* Isolation DEFAULT 事务隔离级别·
timeout -1 事务超时时间(以秒为单位)
read-only false 事务是否只读
事务配置
Name 见上图中配置事务管理的策略
- 通过 “ * ”来匹配对应的方法;
- 配置一个name=“*” 方法
Spring 声明式事务管理 非常重要 (方法二)
1、配置事务管理器
<!-- 1、配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 配置数据源 -->
<property name="DataSource" ref="dataSource"></property>
</bean>
2、配置事务管理的策略
<!-- 2、配置事务管理的策略 -->
<tx:advice id="txManager" transaction-manager="transactionManager">
<tx:attributes>
<!-- 配置一些事务属性 -->
<tx:method name="add*" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="get*" read-only="true" />
<tx:method name="*" isolation="SERIALIZABLE"></tx:method>
</tx:attributes>
</tx:advice>
3、开启声明式事务支持
<!-- 3.2、开启声明式事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
4、在要加入事物的地方配置 @Transactional
@Transactional
@Override
public void addUser(final UserModel um) {
String sql = "insert into user(uuid,name,age) " +
"values('"+um.getUuid()+"','"+um.getName()+"','"+um.getAge()+"') ";
String updateSql = "update user set name ='"+um.getName()+",transaction' where uuid='"+um.getUuid()+"'";
getJdbcTemplate().execute(sql);
int i = 6/0;
getJdbcTemplate().execute(updateSql);
}
Spring 提供了两种编程式事务管理的实现
> 使用TransactionTemplate
> 使用 PlatformTransactionManager接口的实现
TransactionTemplate编程 (方法三)
1、在Spring 中配置TransactionTemplate (前两步跟前面两个一样)
<!-- 3.3、编程式事务支持 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"></property>
</bean>
2、注入至程序中
<bean id="userDao3" class="com.kgc.user.dao.UserDaoImpl3" >
<property name="dataSource" ref="dataSource"></property>
<property name="transactionTemplate" ref="transactionTemplate"></property>
</bean>
3、TransactionTemplate.execute() 一个内部类完成事物的开启和关闭
transactionTemplate.execute(new TransactionCallback() {
...
});
4、将所有需要事务的实现放至事务中
public void addUser(final UserModel um) {
transactionTemplate.execute(new TransactionCallback() {
@Override
public Object doInTransaction(TransactionStatus status) {
try{
String sql = "insert into user(uuid,name,age) " +
"values('"+um.getUuid()+"','"+um.getName()+"','"+um.getAge()+"') ";
/*getJdbcTemplate().execute(sql);*/
String updateSql = "update user set name ='"+um.getName()+",transaction' where uuid='"+um.getUuid()+"'";
getJdbcTemplate().execute(sql);
int i = 6/0;
getJdbcTemplate().execute(updateSql);
}catch(Exception e){
status.setRollbackOnly();
e.printStackTrace();
}
return null;
}
});
}