property-placehodlerlocation="classpath:
cn/itcast/....properties">
●JdbcTemplate使用
dao注入模板:
再dao中提供模板的setter方法,spring进行注入。
dao注入数据源:
【】
在dao集成JdbcDaoSupport,提供数据源setter方法,并再方法中自动创建模板,所以只需要给dao注入数据源即可。
再dao就是使用父类提供getJdbcTemplate()获得模板,并操作。
●api操作
update:
执行DML语句(增删改)
query:
执行DQL语句(查询),使用CallBack回调函数进行ResultSet的数据封装。
例如:
ParameterizedBeanPropertyRowMapper
2事务管理
2.1回顾
●事务:
一组业务操作(ABCD),要么全部成功,要么全部不成功。
例如:
转账
●特性:
ACID,原子性(整体)、一致性(数据)、隔离性(并发)、持久性(结果)。
●隔离问题:
脏读、不可重复读、幻读(虚读)
●隔离级别
readuncomittied:
读未提交,一个事务读到另一个事务没有提交的数据。
存在3问题。
readcommitted:
读已提交,一个事务读到另一个事务提交的数据。
解决:
脏读问题,存放2个
repeatableread:
可重复读,一个事务读到数据都是一样的。
解决:
脏读和不可重复读,存在1个
serializable:
串行化,单事务
2.2回顾事务操作
2.2.1常用事务操作
●ABCD是一个整体
Connectionconn=.....;
try{
//1开启事务
conn.setAutocomit(false);
A
B
C
D
//2提交事务
mit();
}catch(e){
//3回滚事务
conn.rollback();
}fianlly{
//释放资源
conn.close();
}
2.2.2使用保存点事务操作
●AB整体且必须;CD整体且可选。
●保存点:
conn.setSavepoint()可以设置保持点
Connectionconn=.....;
Savepointsavepoint=null;
try{
//1开启事务
conn.setAutocomit(false);//#1
A
B
//###设置保存点
savePoint=conn.setSavepoint();//#2
C
D
//2提交事务//#3
mit();
}catch(e){
if(savepoint==null){//"#2"标记出没有执行到,AB出现异常
conn.rollback();//程序回滚到#1处
}else{
//程序已经执行到了#2之后,CD存在异常
conn.rollback(savepoint);//回滚到执行的保存点处,及回滚到#2处。
CD被回滚,可选
mit();//提交AB,必须
}
}fianlly{
//释放资源
conn.close();
}
2.3介绍
●手动管理事务
●spring手动生产代理对象
●采用aop自动生产代理【☆☆☆】
●注解事务管理【☆☆】
●导入jar包:
spring-tx-...jar(transaction事务)
●spring事务管理:
提供三个核心组件
PlatformTransactionManager,平台事务管理器。
spring是通过事务管理器,来管理事务的。
TransactionDefinition,事务属性(事务详情),给事务管理器所管理的事务,进行详情配置。
例如:
是否只读、隔离级别、超时、传播行为等
TransactionStatus,事务状态,用于记录当前是否已经提交、回滚等。
2.4核心组件详解
2.4.1事务管理器
●spring提供规范PlatformTransactionManager接口,用于管理spring所有的事务。
使用的技术不同,表示平台不同,实现类就不同。
●导入jar包
jdbc:
hibernate:
jdbc:
使用Connection连接管理事务
spring提供连接事务管理器:
DataSourceTransactionManager
hibernate:
使用session管理事务
spring提供hibernate3事务管理:
HibernateTransactionManager
●api详解
TransactionStatusgetTransaction(TransactionDefinition)事务管理器通过事务详情(TransactionDefinition)配置获得事务状态(TransactionStatus)
commit(TransactionStatus)根据事务状态,进行事务提交
rollback(TransactionStatus)根据事务状态,进行事务回滚
结论:
之后不对事务管理器直接进行操作,只是将具体事务管理实例交予spring。
2.4.2事务状态
●spring根据事务的状态,进行事务相应的操作。
2.4.3事务属性(详情)
传播行为:
一个serviceA,需要使用另一个serviceB,两个service之间如何共享事务分类。
分类:
7种
1.PROPAGATION_REQUIRED,required:
b方法必须在事务(默认)
执行当前事务:
如果a方法在执行时已经有事务,b方法直接使用。
没有就创建:
如果a方法没有使用事务,b方法将创建一个新事务。
2.PROPAGATION_SUPPORTS,supports:
有就使用,没有就不使用。
执行当前事务:
如果a方法在执行时已经有事务,b方法直接使用。
没有就无事务操作:
如果a方法没有使用事务,b方法将也不使用事务。
3.PROPAGATION_MANDATORY,mandatory:
有就使用,没有抛异常
执行当前事务:
如果a方法在执行时已经有事务,b方法直接使用。
没有抛异常:
如果a方法没有使用事务,b方法执行直接抛异常。
4.PROPAGATION_REQUIRES_NEW,requires_new,必须保证b方法在新事务中。
创建一个新事务:
如果a方法没有使用事务,b方法直接创建一个事务。
挂起当前事务:
如果a方法已经使用事务,b方法将挂起(暂停)a方法的事务,然后再创建一个事务。
5.PROPAGATION_NOT_SUPPORTED,not_supported,不使用事务
如果a方法没有事务事务,b方法不使用事务
如果a方法使用事务,b方法将a中的事务挂起,然后再以非事务状态执行
6.PROPAGATION_NEVER,naver,如果事务执行,有抛异常
如果a方法没有事务事务,b方法以非事务状态执行
如果a方法使用事务,b方法将抛异常
7.PROPAGATION_NESTED,nested,嵌套事务
使用保存点Savepoint
try{
//开启事务
conn.setAutoCommit(false)
//A
//B
try{
//设置保存点
C
D
}catch(e){
//回滚
conn.rollback(savepoint);
}
//提交
mit();
}catch(){
}
掌握:
PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED
2.5环境搭建
2.5.1导入jar包
2.5.2创建数据库及表
createdatabasespring_day03;
usespring_day03;
createtableaccount(
idintprimarykeyauto_increment,
usernamevarchar(50),
moneyint
);
insertintoaccount(username,money)values('jack','1000');
insertintoaccount(username,money)values('rose','1000');
2.5.3dao实现
publicinterfaceAccountDao{
//转入+money
publicvoidin(StringinUser,intmoney);
//转出-money
publicvoidout(StringoutUser,intmoney);
}
publicclassAccountDaoImplextendsJdbcDaoSupportimplementsAccountDao{
@Override
publicvoidin(StringinUser,intmoney){
this.getJdbcTemplate().update("updateaccountsetmoney=money+?
whereusername=?
",money,inUser);
}
@Override
publicvoidout(StringoutUser,intmoney){
this.getJdbcTemplate().update("updateaccountsetmoney=money-?
whereusername=?
",money,outUser);
}
}
2.5.4service
publicinterfaceAccountService{
publicabstractvoidtransfer(StringoutUser,StringinUser,intmoney);
}
publicclassAccountServiceImplimplementsAccountService{
privateAccountDaoaccountDao;
publicvoidsetAccountDao(AccountDaoaccountDao){
this.accountDao=accountDao;
}
@Override
publicvoidtransfer(StringoutUser,StringinUser,intmoney){
accountDao.out(outUser,money);
inti=1/0;
accountDao.in(inUser,money);
}
}
2.5.5xml配置
●位置:
src/applicationContext.xml
--0配置数据源-->
mysql:
//localhost:
3306/spring_day03">
--1配置dao-->
--2配置service-->
2.5.6测试
publicstaticvoidmain(String[]args){
StringxmlPath="applicationContext.xml";
ApplicationContextapplicationContext=newClassPathXmlApplicationContext(xmlPath);
AccountServiceaccountService=(AccountService)applicationContext.getBean("accountService");
accountService.transfer("jack","rose",100);
}
2.6手动方式
●spring提供事务模板手动管理事务:
TransactionTemplate
事务模板,需要注入事务管理器
2.6.1修改配置文件
--0配置数据源-->
mysql:
//localhost:
3306/spring_day03">
--1配置dao-->
--2配置service-->
--2.1注入dao-->
--2.2注入事务模板-->
--#1事务管理器-->
--#2事务模板,需要事务管理器-->
2.6.2修改service实现
publicclassAccountServiceImplimplementsAccountService{
privateAccountDaoaccountDao;
publicvoidsetAccountDao(AccountDaoaccountDao){
this.accountDao=accountDao;
}
//提供事务模板
privateTransactionTemplatetransactionTemplate;
publicvoidsetTransactionTemplate(TransactionTemplatetransactionTemplate){
this.transactionTemplate=transactionTemplate;
}
@Override
publicvoidtransfer(finalStringoutUser,finalStringinUser,finalintmoney){
transactionTemplate.execute(newTransactionCallbackWithoutResult(){
@Override
protectedvoiddoInTransactionWithoutResult(TransactionStatusarg0){
accountDao.out(outUser,money);
inti=1/0;
accountDao.in(inUser,money);
}
});
}
}
2.7spring手动创建代理
●TransactionProxyFactoryBean,用于手动设置代理对象,此代理对象具有事务管理功能。
●之后必须从容器获得自己编写代理类
2.7.1xml配置文件
//www.springframework.org/schema/beans"
xmlns:
xsi="http:
//www.w3.org/2001/XMLSchema-instance"
xmlns:
aop="http:
//www.springframework.org/schema/aop"
xsi:
schemaLocation="http:
//www.springframework.org/schema/beans
http:
//www.springframework.org/schema/beans/spring-beans.xsd
http:
//www.springfram