概念
JDBC编程事务管理
可以清楚的控制事务的边界,事务控制粒度化细(编程方式)
JDBC声明事务管理
事务相关的API不用介入程序之中,将事务管理与实际业务代码解耦(配置XML的方式)
Spring提供两种方式实现编程式的事务管理
1、实现PlatformTransactionManager接口
2、使用事务模板TransactionTemplate
使用PlatformTransactionManager管理事务的大致流程
1、指定PlatformTransactionManager的实现类
2、定义事务属性TransactionDefinition
3、将事务定义传送给TransactionStatus
4、将欲进行的事务用try..catch语句封起来
5、如果事务出错,调用PlatformTransactionManager的rollback方法
使用事务模板TransactionTemplate
1、需要封装一个TransactionManager
2、创建事务回滚类3、执行TransactionManager的execute方法
一、使用PlatformTransactionManager管理事务
操作步骤:
1、在applicationContex.xml中添加相应的dataSource和transactionManager
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
2、创建测试类PlatformTransactionManagerDemo
import javax.sql.DataSource;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
/*
* 直接使用PlatformTransactionManager实现类进行事务管理
*/
public class PlatformTransactionManagerDemo {
public static void main(String[] args) {
ClassPathXmlApplicationContext cpx = new ClassPathXmlApplicationContext("beans.xml");
/*
* 初始化事务
*/
PlatformTransactionManager ptm = (PlatformTransactionManager) cpx.getBean("transactionManager");
DefaultTransactionDefinition dtd = new DefaultTransactionDefinition();
dtd.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus ts = ptm.getTransaction(dtd);
/*
* 进行事务
*/
try {
DataSource dSource = (DataSource) cpx.getBean("dataSource");
JdbcTemplate jt = new JdbcTemplate(dSource);
jt.execute("insert into person values(98,'test',23)");
jt.execute("insert into person values(1,'test',33)");//违反唯一约束的测试语句
} catch (Exception e) {
// TODO: handle exception
ptm.rollback(ts);
e.printStackTrace();
}
}
}
3、测试函数,打印出相应的异常
org.springframework.dao.DuplicateKeyException: StatementCallback;
SQL [insert into person values(1,'rty',33)];
ORA-00001: 违反唯一约束条件 (SCOTT.SYS_C0011509);
nested exception is java.sql.SQLException: ORA-00001: 违反唯一约束条件 (SCOTT.SYS_C0011509)
Caused by: java.sql.SQLException: ORA-00001: 违反唯一约束条件 (SCOTT.SYS_C0011509)
【疑问是:这玩意儿不违反约束也没添加进去 orz】
【解决方法:(存有疑问的很二的方法)】加一条 jt.execute("commit");
存疑待解救!
二、使用事务模板TransactionTemplate管理事务
操作步骤:
1、使用PlatformTransactionManager的源码
2、创建测试类TransactionTemplateDemo
/*
* 直接使用TransactionTemplate实现类进行事务管理
* 编程式事务管理最大的缺点:侵入代码
* 好处:细粒度化,可以针对某一行进行控制
* 当数据极度敏感是,使用编程的事务管理
*/
public class TransactionTemplateDemo {
public static void main(String[] args) {
ClassPathXmlApplicationContext cpx = new ClassPathXmlApplicationContext("beans.xml");
/*
* 初始化事务
*/
PlatformTransactionManager ptm = (PlatformTransactionManager) cpx.getBean("transactionManager");
TransactionTemplate tt = new TransactionTemplate(ptm);
DataSource dSource = (DataSource) cpx.getBean("dataSource");
final JdbcTemplate jt = new JdbcTemplate(dSource);
/*
* 进行事务
*/
tt.execute( // 使用内部类
new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus arg0) {
jt.execute("insert into person values(99,'test',23)");
jt.execute("insert into person values(1,'test',33)");
}
}
);
}
}
3、运行打印异常
Exception in thread "main" org.springframework.dao.DuplicateKeyException: StatementCallback;
SQL [insert into person values(98,'tyry',23)];
ORA-00001: 违反唯一约束条件 (SCOTT.SYS_C0011509);
nested exception is java.sql.SQLException: ORA-00001: 违反唯一约束条件 (SCOTT.SYS_C0011509)