簡體   English   中英

@Transactional 不適用於 readOnly = true

[英]@Transactional not working with readOnly = true

我有以下代碼,我在其中設置@Transactional(readOnly = true)

main()方法中的代碼:

    ApplicationContext context = Utils.getContext();
    AnnotatedCrudDao service = new AnnotatedCrudDao();
    DataSource dataSource = (DataSource) context.getBean("mySqlDataSource");
    service.setDataSource(dataSource);
    service.insert(account, user, movie);


@Transactional
public class AnnotatedCrudDao extends JdbcDaoSupport {

    private static Logger logger;

    static {
    logger = Logger.getLogger(AnnotatedCrudDao.class);
    }


    @Transactional(readOnly = true)
    public void insert(Account account, User user, MovieTicket movie) {

    TicketUtils.insertAccount(getJdbcTemplate(), account);
    TicketUtils.insertUser(getJdbcTemplate(), user);
    TicketUtils.insertMovie(getJdbcTemplate(), movie);
    }
}

class TicketUtils{

    public static void insertUser(JdbcTemplate template, User user) {
    String queryUser = "INSERT INTO t_user_txn (ID, NAME, ACCOUNT_ID, TICKETID) VALUES (?,?,?,?)";
    logger.debug("queryUser" + queryUser);
    template.update(queryUser, new Object[] { user.getId(), user.getName(),
    user.getAccount().getId(), user.getTicketId() });
    }

    public static void insertMovie(JdbcTemplate template, MovieTicket movie) {
    String queryMovie = "INSERT INTO t_movieticket_txn (ID, MOVIENAME, TOTALTICKETSCOUNT, PRICE) VALUES (?,?,?,?)";
    logger.debug("queryMovie:" + queryMovie);
    template.update(queryMovie, new Object[] { movie.getId(),
    movie.getMovieName(), movie.getTotalTicketsCount(),
    movie.getPrice() });
    }

    public static void insertAccount(JdbcTemplate template, Account account) {
    String queryAccount = "INSERT INTO t_account_txn (ID, AMOUNT) VALUES (?,?)";
    logger.debug("queryAccount:" + queryAccount);
    template.update(queryAccount, new Object[] { account.getId(),
    account.getAmount() });
    }

}

背景:

    <bean id="mySqlDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@localhost:1521:qadb7"/>
    <property name="username" value="tp2"/>
    <property name="password" value="tp2"/>
    </bean>

    <bean id="dsTxnMgr" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="mySqlDataSource" />
    </bean>

    <!-- Add this tag to enable annotations transactions -->
    <tx:annotation-driven transaction-manager="dsTxnMgr" />

即使我已經為插入方法設置了@Transactional(readOnly = true) ,仍然在執行插入操作。 不應將屬性readOnly設置為true應該注意不能在此方法上執行插入。

幾件事

  1. 您正在創建自己的 dao 實例,這不是 spring 管理的,因此@Transactional注釋沒有做任何事情。
  2. readonly="true"強制執行任何操作,不要期望拋出異常或插入不會發生,很少有 jdbc 提供程序實際使用readOnly標志執行某些操作。 它只是對底層系統的一個提示,僅此而已。 通常,它被 Hibernate 等 ORM 工具使用和理解。 但是對於大多數情況下的普通 JDBC 訪問,它被簡單地忽略了。

您需要放置一個@Repository注釋以使其工作

@Transactional
@Repository
public class AnnotatedCrudDao extends JdbcDaoSupport {

您正在自己創建AnnotatedCrudDao對象。 因此,Spring 無法處理它並添加@Transactional行為。

AnnotatedCrudDao service = new AnnotatedCrudDao();

讓 Spring 管理您的對象。 在您的上下文中為它聲明一個<bean>元素並改用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM