Annotation-Based Transactions in Spring

ANNOTATING THE JAVA INTERFACE

With Spring, you typically apply transaction annotations either to Java interfaces for service beans, or else to the service beans themselves. If you apply the annotations to the interfaces then the transaction definition holds true for any classes implementing those interfaces. We'll do that here, but remember that you can apply the annotations to the service beans themselves as well.

Here's an interface for a simple article service. This service allows the application to get an article by ID, and also to post a comment for a given article.

package myapp.service;

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import myapp.model.Article;
import myapp.model.Comment;

@Transactional(
    propagation = Propagation.REQUIRED,
    isolation = Isolation.DEFAULT,
    readOnly = true)
public interface ArticleService {
    
    Article getArticle(long articleId);
    
    @Transactional(readOnly = false)
    void postComment(long articleId, Comment comment);
}

The first thing to notice is again just how ridiculously simple this is. I probably don't need to explain it but I will anyway just to be safe. The @Transactional annotation we define on the interface is setting default values for the various methods that form the interface. So we are saying here that unless the method itself specifies otherwise, we want Propagation.REQUIRED for the propagation behavior, we want the default isolation level, and we want to flag methods as read-only.

The only other piece to mention is that I've overridden the readOnly setting for the postComment method since that's obviously a write method.

If it could be any simpler I'm not sure how. Now let's look at the Spring configuration file.

THE SPRING CONFIGURATION FILE

Here it is:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    
    <!-- Wire beans here -->
    ...

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        ...
    </bean>
    
    <!-- This tells Spring to activate annotation-driven transactions -->
    <tx:annotation-driven/>
</beans>

That's it—really! Make sure you include both the aop and tx namespaces and schema locations since that's where the magic lives. You have to wire your beans up just like you normally would (though note that you can even use annotations to autowire your beans). And you have to provide a transaction manager of one kind or another. I'm using the Hibernate 3 HibernateTransactionManager but use whatever you want. If you give your transaction manager the id transactionManager, then you can take advantage of a little Spring convention-over-configuration: <tx:annotation-driven> will pick that up automatically. (And if you want to call your transaction manager something else, that's fine too. Just reference that ID using the transaction-manager attribute of the <tx:annotation-driven> element.)

Oh, the <tx:annotation-driven> element just tells Spring that you want it to pick the transaction definitions up from the Java annotations. I'm not sure how it works behind the scenes, but I think Spring will run through the beans in your context and create the necessary transaction aspects. Not positive about that—if you know the details, I'm interested—but in any case you end up with annotation-driven transactions. Nice!

That's all there is. As always let me know if you have comments or questions.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值