spring事务的实现原理,不搞明白,很不爽。

yeshenghai 2007-02-04 08:45:30
刚学spring,在spring的事务编程中有一些事务的原理问题不明白?
1,一般在单一数据库中,如果手动方式写事务的话,我对事务的理解就是
(1)首先在数据库连接中
con.setAutocommit(false)设置手动提交事务
(2)然后执行sql语句,最后提交。
stmt = con.createStatement();
stmt.executeUpdate("UPDATE user SET age = 18 WHERE id = 'erica'");
con.commit()
2,可是在spring的声明式的事务编程中,我有点不明白,举以下一个例子,但这个例子中,我没法体现上面的事务步骤?首先设置con.setAutocommit(false),然后提交
(1)假设数据源是基于绑定在容器的JNDI上面,并且只有一个数据库
在spring配置文件中,为了演示的方便,我简略了一些代码,有些代码没有写出来,
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>jdbc/sample</value>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTrans
actionManager"
/>
<bean id="userDAO" class="net.xiaxin.dao.UserDAO">
<property name="dataSource">
<ref local="dataSource" />
</property>
<property name="transactionManager">
<ref local="transactionManager" />
</property>
</bean>

(2)在java的源文件中,是这样写的:
public class UserDAO {
private DataSource dataSource;
private PlatformTransactionManager transactionManager;
public PlatformTransactionManager getTransactionManager() {
return transactionManager;
}
public void setTransactionManager(PlatformTransactionManager
transactionManager) {
this.transactionManager = transactionManager;
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void insertUser() {
TransactionTemplate tt =
new TransactionTemplate(getTransactionManager());
tt.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
JdbcTemplate jt = new JdbcTemplate(getDataSource());
jt.update(
"insert into users (username) values ('xiaxin');");
jt.update(
"insert into users (id,username) values(2,
'erica');");
return null;
}
});
}
}

(3)其中我的问题是针对以上的java源代码,它如何体现了类似手动写代码时候的事务原理?
首先设置手动提交事务,然后提交?
产生这个问题的疑惑是:以下这段代码,Spring中的JdbcTemplate操作采用的是JDBC默认的AutoCommit模式,也就是说我们还
无法保证数据操作的原子性(要么全部生效,要么全部无效),
JdbcTemplate jt = new JdbcTemplate(getDataSource());
jt.update(
"insert into users (username) values ('xiaxin');");//执行这sql语句后,我认为应该马上提交,何来的事务?
jt.update(
"insert into users (id,username) values(2,
'erica');");//执行这sql语句后,我认为应该马上提交,何来的事务?
return null;
我的问题在于:::::::::
虽然,我举个例子(UserDAO类中,它已经获得一个transactionManager,而且,这个transactionManager已经获得了一个dataSource(不知道这样做有什么用?),好像这个transactionManager在UserDAO的事务中不起什么作用,反而起作用的JdbcTemplate 又体现不了手动写事务时的事务原理?为什么,请大家解释一下吧?
...全文
3992 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
superdcj 2011-02-16
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 bao110908 的回复:]

Spring 事务采用了一种称为“事务上下文”的 J2EE 模式进行设计的。
[/Quote]Hehe
hepeng_8 2011-02-16
  • 打赏
  • 举报
回复
同惑
  • 打赏
  • 举报
回复
Spring 事务采用了一种称为“事务上下文”的 J2EE 模式进行设计的。
hlf297512399 2011-02-15
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 luhao 的回复:]
你这种事务方式写的很不好
根本就没用到声明式的事务

<!-- 事务管理 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"……
[/Quote]

很好
luhao 2008-09-08
  • 打赏
  • 举报
回复
你这种事务方式写的很不好
根本就没用到声明式的事务

<!-- 事务管理 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!-- 事务拦截器bean需要依赖注入一个事务管理器 -->
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<!-- 下面定义事务传播属性-->
<props>
<prop key="list*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED,-Exception</prop>
</props>
</property>
</bean>

<!-- 定义BeanNameAutoProxyCreator-->
<bean id="beanNameAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!-- 指定对满足哪些bean name的bean自动生成业务代理 -->
<property name="beanNames">
<!-- 下面是所有需要自动创建事务代理的bean-->
<list>
<value>*Service</value>
</list>
<!-- 此处可增加其他需要自动创建事务代理的bean-->
</property>
<!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器-->
<property name="interceptorNames">
<list>
<!-- 此处可增加其他新的Interceptor -->
<value>transactionInterceptor</value>
</list>
</property>
</bean>

这样写才能体现出声明式的优势
xiao7cn 2008-09-08
  • 打赏
  • 举报
回复
通过研究Spring的代码,发现它在方法调用之前,把数据库连接放进了ThreadLocal里面,方法里面用HibernateTemplate的连接用的其实是早就在ThreadLocal里的。终于明白了,哈哈。
youjianbo_han_87 2008-09-08
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xiao7cn 的回复:]
通过研究Spring的代码,发现它在方法调用之前,把数据库连接放进了ThreadLocal里面,方法里面用HibernateTemplate的连接用的其实是早就在ThreadLocal里的。终于明白了,哈哈。
[/Quote]
这只是为了避免同步降低效率,实现高效的多处理方式
xiao7cn 2008-09-07
  • 打赏
  • 举报
回复
感觉Spring的声明式事务太神奇了。。

我们都知道事务管理是通过获得方法里的数据库连接实现的,Spring怎么就这么聪明,知道要用哪个连接来管理事务,其中的奥迷不是这么简单哦。。
youjianbo_han_87 2008-09-05
  • 打赏
  • 举报
回复
不知道楼主在说什么,spring的事务保护原理不是很懂,但是如果配置好了事务保护,和要保护的操作,那么,当用户使用此类操作的时候,该操作就自动放入事务中,和jdbc事务原理没有任何区别(也就是他们的原理相同),只要执行过程发生异常,则回滚,否则提交,其实也就是spring在你指定的操作两端自动加上事务段,和你手动加事务处理没什么区别(本人浅见),楼主看过配置事务保护的例子吗
xiao7cn 2008-09-05
  • 打赏
  • 举报
回复
同惑,希望高人指点中。。。
alihand 2008-08-05
  • 打赏
  • 举报
回复
我也有同样的疑惑。解答不了。帮顶

67,549

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧