1、什么是事务?
事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用。就是把一系列的操作当成原子性去执行。
2、Spring事务
Spring 的声明式事务管理在底层是建立在 AOP 的基础上。其本质是在方法前后进行拦截,然后在目标方法开始之前创建一个事务,在执行这目标方法结束后,根据执行情况提交或进行回滚事务。
在写代码过程中碰到的错误:
-
使用
AOP
的时候一定要记得导入:
aopalliance.jar
,
aspectjweaver-1.8.9.jar
两个包
-
在
beans
里添加好
tx
与
aop
命名空间
栗子:
执行下面的方法体
public
List<User> selectUser()
{
User u=
new
User();
u.setId(
“05”
);u.setName(
”
林木
”
);u.setAge(17);u.setSex(
”
男
”
);
insertUser(u);
deleteUser(
“03”
);
List<User> list=
sst
.selectList(
“com.user.UserMapper.selectUser”
);
return
list;
}
|
SQL语句映射
<
select
id
=
“selectUser”
resultType
=
“com.user.User”
>
select*from users
</
select
>
<
insert
id
=
“insertUser”
parameterType
=
“com.user.User”
>
insert into users values(#{id},#{name},#{age},#{sex})
</
insert
>
<
delete
id
=
“deleteUser”
parameterType
=
“com.user.User”
>
delete user where id=#{id}
</
delete
>
|
这里将delete
的SQL
语句写错
Test
public
static
void
main(String[] args) {
ApplicationContext ac=
new
ClassPathXmlApplicationContext(
“Beans.xml”
);
UserDao ud=(UserDao)ac.getBean(
“userDao”
);
List<User> li=ud.selectUser();
for
(User u:li)
{
System.
out
.println(u);
}
|
在一个方法中执行insert delete select 3个操作其中delete是错误的,这里的运行结果会出错,那么其他两个方法能否执行?
运行结果
这里提示delete
错误,但是数据库中insert
的数据成功插入
默认配置下一个方法中有一处错误事务不会回滚,没有错的代码还是会正常执行,这样不利于维护数据的一致性。
为了解决这种问题,需要用到Spring 的声明式事务
配置声明式事务
Xml配置
<
bean
id
=
“dataSource”
class
=
“org.springframework.jdbc.datasource.DriverManagerDataSource”
>
<
property
name
=
“driverClassName”
value
=
“com.microsoft.sqlserver.jdbc.SQLServerDriver”
></
property
>
<
property
name
=
“url”
value
=
“jdbc:sqlserver://127.0.0.1:1433;databaseName=test”
></
property
>
<
property
name
=
“username”
value
=
“sa”
></
property
>
<
property
name
=
“password”
value
=
“root”
></
property
>
</
bean
>
<!–
声明式事务开始
–>
<!–
事务管理器
–>
<
bean
id
=
“txManager”
class
=
“org.springframework.jdbc.datasource.DataSourceTransactionManager”
>
<
property
name
=
“dataSource”
ref
=
“dataSource”
></
property
>
</
bean
>
<!–
配置事务通知
–>
<
tx:advice
id
=
“txAdvice”
transaction-manager
=
“txManager”
>
<
tx:attributes
>
<!–
配置哪些方法,使用怎样的事务
–>
<
tx:method
name
=
“insert*”
propagation
=
“REQUIRED”
/>
<
tx:method
name
=
“update*”
propagation
=
“REQUIRED”
/>
<
tx:method
name
=
“delete*”
propagation
=
“REQUIRED”
/>
<
tx:method
name
=
“select*”
propagation=
“REQUIRED”
/>
<
tx:method
name
=
“*”
propagation
=
“REQUIRED”
></
tx:method
>
</
tx:attributes
>
</
tx:advice
>
<
aop:config
>
<
aop:pointcut
expression
=
“execution(* com.user.*.*(..))”
id
=
“pointcut”
/>
<
aop:advisor
advice-ref
=
“txAdvice”
pointcut-ref
=
“pointcut”
/>
</
aop:config
>
<!–
声明式事务结束
–>
|
Propagation
的类型
|
说明
|
REQUIRED
|
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
|
SUPPORTS
|
支持当前事务,如果当前没有事务,就以非事务方式执行。
|
MANDATORY
|
使用当前的事务,如果当前没有事务,就抛出异常
|
REQUIRES_NEW
|
新建事务,如果当前存在事务,把当前事务挂起。
|
NOT_SUPPORTED
|
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
|
NEVER
|
以非事务方式执行,如果当前存在事务,则抛出异常。
|
NESTED
|
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与REQUIRED类似的操作。
|
|
配置好之后再来测试一下这个方法
public
List<User> selectUser()
{
User u=
new
User();
u.setId(
“06”
);u.setName(
“wwww”
);u.setAge(17);u.setSex(
”
男
”
);
insertUser(u);
deleteUser(
“05”
);
List<User> list=
sst
.selectList(
“com.user.UserMapper.selectUser”
);
return
list;
}
|
测试结果:
查看以下数据是否插入到数据库中
u.setId(
“06”
);u.setName(
“wwww”
);u.setAge(17);u.setSex(
”
男
”
);
insertUser(u);
|
由此可见上面写的事务管理使出错的方法回滚,所以数据没有被添加到数据库中。