jiveJdon4.1 中关于事务的的疑惑

在com.jdon.jivejdon.service.util中有定义了一个JtaTransactionUtil 事务工具类


private TransactionManager transactionManager;

public JtaTransactionUtil(String[] txpram) {
if (txpram[0].equals(JTA)) {
try {
transactionManager = (TransactionManager) new InitialContext().lookup(txpram[1]);
} catch (NamingException e) {
e.printStackTrace();
}
}
}

在com.jdon.jivejdon.service.services.xml有一段定义如下:


<!-- Tansaction JNDI -->
<component name="jtaTransactionUtil"
class=
"com.jdon.jivejdon.service.util.JtaTransactionUtil">
<!--<constructor value=
"JTA"/>
<constructor value=
"java:/TransactionManager"/> -->
<constructor value=
"JDBC"/>

这里不是使用JDBC吗,如果是的话,那上面JtaTransactionUtil类怎么能够取得transactionManager实例对象呢,如果取不到,那么JtaTransactionUtil的共它方法怎么能用呀

比如:下面的方法怎么能使用呢


public void beginTransaction() throws Exception {
if (!checkIsJTA())
return;
transactionManager.begin();
}

public void commitTransaction() throws Exception {
if (!checkIsJTA())
return;
transactionManager.commit();
}

public void rollback() {
if (transactionManager != null) {
try {
transactionManager.rollback();
} catch (Exception ex) {
}
}
}

真是想不通呢,如果上面的配置配成
<!-- Tansaction JNDI -->
<component name="jtaTransactionUtil"
class="com.jdon.jivejdon.service.util.JtaTransactionUtil">

<constructor value="JTA"/>
<constructor value="java:/TransactionManager"/>
<!--<constructor value="JDBC"/>-->

这样才对吧,但是论坛像上面的都可以成功,所以想不明白

if (!checkIsJTA())
return;

如果不是JTA就直接返回了,用自动提交事务

补充一下,我是在看增加论坛信息过程时,感觉上面看不太明白,不过也收获挺多的,希望道友可以指点一下

我是直接从服务层开如看的
ForumMessageShell.java中的


public void createTopicMessage(EventModel em) throws Exception {
...

if (!UtilValidate.isEmpty(forumMessage.getMessageVO().getBody())){ messageKernel.addTopicMessage(em);
}
}

addTopicMessage再调用MessageTransactionPersistence的


public void insertTopicMessage(EventModel em) throws Exception {
logger.debug("enter createTopicMessage");
ForumMessage forumMessage = (ForumMessage) em.getModelIF();
try {
jtaTransactionUtil.beginTransaction();
messageRepository.createTopicMessage(forumMessage);
logger.debug("createTopicMessage ok!");
jtaTransactionUtil.commitTransaction();
} catch (Exception e) {
jtaTransactionUtil.rollback();
String error = e + " createTopicMessage forumMessageId=" + forumMessage.getMessageId();
logger.error(error);
throw new Exception(error);
}
}

这里开始提交创建论坛发贴的事务,所以我想研究一下jtaTransactionUtil里的JTA是怎么使用的,看了下配置,就产生了主题贴的疑问。

因为我想用这种方式处理我刚开始的一个小系统,因为有多个数据库,所以需要JTA的支持。


感觉收获也是挺多的,论坛的分层很清淅(一开始看挺混乱的,转来转去,慢慢领悟到了,呵)

多谢oojdon,这样一说我才明白了些。

在没搞明白之前的时候,我自己模仿了一个JDBC的事务,不知道有没有这个必要呢。因为我是小系统,不想像论坛一样,好多类跳来转去,最终由仓储的dao来持久。


public class JDBCTransactionUtil {
private static final Logger logger = LoggerFactory.getLogger(JDBCTransactionUtil.class);

private JdbcTempSource jdbcTempSource;
private Connection con;

public JDBCTransactionUtil(String jndi) throws Exception {
this.jdbcTempSource = new JdbcTempSource(jndi);
try {
this.con = jdbcTempSource.getDataSource().getConnection();
} catch (SQLException e) {
logger.error("[JDBCTransactionUtil]获取getConnection出错:{}",e);
throw new Exception(e);
}
}

/**
* 开始JDBC事务
* */
public void beginTransaction() throws SQLException {
con.setAutoCommit(false);
}

/**
* 提交事务
*
* @throws SQLException
* */

public void commitTransaction() throws SQLException {
con.commit();
}

/**
* 回滚事务
*
* @throws SQLException
* */

public void rollback() throws SQLException {
con.rollback();
}

/**
* 返回是否自动提交标志
*
* @return boolean
* @throws SQLException
*/

public boolean isAutoCommit() throws SQLException {
return con.getAutoCommit();
}

public JdbcTempSource getJdbcTempSource() {
return jdbcTempSource;
}

public void setJdbcTempSource(JdbcTempSource jdbcTempSource) {
this.jdbcTempSource = jdbcTempSource;
}

}

多谢oojdon,这样一说我才明白了些。

在没搞明白之前的时候,我自己模仿了一个JDBC的事务,不知道有没有这个必要呢。因为我是小系统,不想像论坛一样,好多类跳来转去,最终由仓储的dao来持久。


public class JDBCTransactionUtil {
private static final Logger logger = LoggerFactory.getLogger(JDBCTransactionUtil.class);

private JdbcTempSource jdbcTempSource;
private Connection con;

public JDBCTransactionUtil(String jndi) throws Exception {
this.jdbcTempSource = new JdbcTempSource(jndi);
try {
this.con = jdbcTempSource.getDataSource().getConnection();
} catch (SQLException e) {
logger.error("[JDBCTransactionUtil]获取getConnection出错:{}",e);
throw new Exception(e);
}
}

/**
* 开始JDBC事务
* */

public void beginTransaction() throws SQLException {
con.setAutoCommit(false);
}

/**
* 提交事务
*
* @throws SQLException
* */

public void commitTransaction() throws SQLException {
con.commit();
}

/**
* 回滚事务
*
* @throws SQLException
* */

public void rollback() throws SQLException {
con.rollback();
}

/**
* 返回是否自动提交标志
*
* @return boolean
* @throws SQLException
*/

public boolean isAutoCommit() throws SQLException {
return con.getAutoCommit();
}

public JdbcTempSource getJdbcTempSource() {
return jdbcTempSource;
}

public void setJdbcTempSource(JdbcTempSource jdbcTempSource) {
this.jdbcTempSource = jdbcTempSource;
}

}

你这个数据库连接共享了,做成了类属性变量。
要每次请求每次连接。数据连接多线程不安全。

[该贴被oojdon于2010-12-24 10:55修改过]

2010年12月24日 10:52 "oojdon"的内容
你这个数据库连接共享了,做成了类属性变量。
要每次请求每次连接。数据连接多线程不安全。 ...

多谢,以后还要在这里跟你们多多学习


private JdbcTempSource jdbcTempSource;
private static Connection con;

public JDBCTransactionUtil(String jndi) throws Exception {
this.jdbcTempSource = new JdbcTempSource(jndi);
try {
if(con==null)
con = jdbcTempSource.getDataSource().getConnection();
} catch (SQLException e) {
logger.error("[JDBCTransactionUtil]获取getConnection出错:{}",e);
throw new Exception(e);
}
}

这样写可以吗
[该贴被freesea1于2010-12-24 13:59修改过]

在MessageTransactionPersistence的 insertTopicMessage方法中,为什么事务提交放在异常段中呢,这样不对吧?因该是放在logger.debug("createTopicMessage ok!");之后才对


public void insertTopicMessage(EventModel em) throws Exception {
logger.debug("enter createTopicMessage");
ForumMessage forumMessage = (ForumMessage) em.getModelIF();
try {
jtaTransactionUtil.beginTransaction();
messageRepository.createTopicMessage(forumMessage);
logger.debug(
"createTopicMessage ok!");
} catch (Exception e) {
jtaTransactionUtil.commitTransaction();
//这里为什么放在异常这里呢
jtaTransactionUtil.rollback();
String error = e +
" createTopicMessage forumMessageId=" + forumMessage.getMessageId();
logger.error(error);
throw new Exception(error);
}
}

我这里代码不是你那样的呀,不可能在异常出现了提交事务的啊。
对于前面那个问题,如果你非要在connection上管理事务,那你需要改造现有代码,用ThreadLocal来hold数据库连接

呵呵,还没提交就要扑捉异常-。-非一般的理解,摆错位置了吧