<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 41  文章 - 29  trackbacks - 0
    <2009年4月>
    2930311234
    567891011
    12131415161718
    19202122232425
    262728293012
    3456789

    常用鏈接

    留言簿(5)

    隨筆分類(28)

    隨筆檔案(23)

    收藏夾(6)

    Inside JVM

    Java

    java performance

    Solr

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    This message is a summary based on a very good article (http://www.ibm.com/developerworks/java/library/j-ts1.html?S_TACT=105AGX02&S_CMP=EDU) and focusing on common mistakes when implementing transactions in the Java platform. The original article is aimed to discuss Transaction Strategy. Here, we just want to discuss the common mistakes on transaction management.

    Why we need Transaction?

    The most common reason for using transactions in an application is to maintain a high degree of data integrity and consistency. Transactions improve the quality, integrity, and consistency of your data and make your applications more robust. Implementation of successful transaction processing in Java applications is not a trivial exercise, and it's about design as much as about coding. Although most of this article's code examples use the Spring Framework (version 2.5), the transaction concepts are the same as for the EJB 3.0 specification.

    O/R Mapping Transaction pitfalls

    Pitfall1: ORM-based frameworks (such as hibernate, TopLink or JPA) require a transaction in order to trigger the synchronization between the object cache and the database. It is through a transaction commit that the SQL code is generated and the database affected by the desired action (that is, insert, update, delete). Without a transaction there is no trigger for the ORM to generate SQL code and persist the changes, so the method simply ends — no exceptions, no updates. If you are using an ORM-based framework, you must use transactions. You can no longer rely on the database to manage the connections and commit the work.
    public class TradingServiceImpl {
       @PersistenceContext(unitName
    ="trading") EntityManager em;
      
       
    public long insertTrade(TradeData trade) throws Exception {
           em.persist(trade);
           
    return trade.getTradeId();
       }

    }
    Solution:: the method insertTrade must have transactional setting, such as @Transactional annotation, or codes, or AOP-like configurations.

    Spring Framework @Transactional annotation pitfalls

    Pitfall2: When using the @Transactional annotation in Spring, you must add the following line to your Spring configuration file:
    <tx:annotation-driven transaction-manager="transactionManager">
    </tx:annotation-driven>
    Without it, the @Transactional annotation is ignored, resulting in no transaction being used in your code. NOTE: when using the @Transactional annotation by itself without any parameters, the propagation mode is set to REQUIRED, the read-only flag is set to false, the transaction isolation level is set to the database default (usually READ_COMMITTED), and the transaction will not roll back on a checked exception.

    @Transactional read-only flag pitfalls

    Pitfall3: the improper use of the read-only flag on the Spring @Transactional annotation.
    3.1:
    The read-only flag is somewhat meaningless when you use it for JDBC-based Java persistence and causes additional overhead when an unnecessary transaction is started.

    3.2: when you use an ORM-based framework, the read-only flag is quite useless and in most cases is ignored.

    Example 1:
    @Transactional(readOnly = true, propagation=Propagation.SUPPORTS)

    public Long insertTrade(TradeData trade) throws Exception {

    //JDBC Code

    }
    When the insertTrade() method executes, does it:
    1. Throw a read-only connection exception
    2. Correctly insert the trade order and commit the data
    3. Do nothing because the propagation level is set to SUPPORTS
    The correct answer is 2. The trade order is correctly inserted into the database, even though the read-only flag is set to true and the transaction propagation set to SUPPORTS. But how can that be? No transaction is started because of the SUPPORTS propagation mode, so the method effectively uses a local (database) transaction. The read-only flag is applied only if a transaction is started. In this case, no transaction was started, so the read-only flag is ignored.

    Example 2:
    @Transactional(readOnly = true, propagation=Propagation.REQUIRED)

    public long insertTrade(TradeData trade) throws Exception {

    //JDBC code

    }
    When executed, does the insertTrade() method:
    1. Throw a read-only connection exception
    2. Correctly insert the trade order and commit the data
    3. Do nothing because the read-only flag is set to true
    The correct answer is 2. An exception will be thrown, indicating that you are trying to perform an update operation on a read-only connection. Because a transaction is started (REQUIRED), the connection is set to read-only. Sure enough, when you try to execute the SQL statement, you get an exception telling you that the connection is a read-only connection.

    So, the summary is the read-only flag is that you need to start a transaction in order to use it.. However, why would you need a transaction if you are only reading data? The answer is that you don't.

    Example3:
    @Transactional(readOnly = true, propagation=Propagation.REQUIRED)

    public long insertTrade(TradeData trade) throws Exception {

       em.persist(trade);

       
    return trade.getTradeId();

    }
    Does the insertTrade() method:
    1. Throw a read-only connection exception
    2. Correctly insert the trade order and commit the data
    3. Do nothing because the readOnly flag is set to true
     In some cases the answer is 3, but in most cases (particularly when using JPA) the answer is 2. When you are generating a key on an insert, the ORM framework will go to the database to obtain the key and subsequently perform the insert. For some vendors, such as Hibernate, the flush mode will be set to MANUAL, and no insert will occur for inserts with non-generated keys.

     However, other vendors, like TopLink, will always perform inserts and updates when the read-only flag is set to true. Although this is both vendor and version specific, the point here is that you cannot be guaranteed that the insert or update will not occur when the read-only flag is set, particularly when using JPA as it is vendor-agnostic.

    Example4:
    @Transactional(readOnly = true)

    public TradeData getTrade(long tradeId) throws Exception {

       
    return em.find(TradeData.class, tradeId); 
    }
    Does the getTrade() method:
    1. Start a transaction, get the trade order, then commit the transaction
    2. Get the trade order without starting a transaction 
    The correct answer here is 1. A transaction is started and committed. Don't forget: the default propagation mode for the @Transactional annotation is REQUIRED. This means that a transaction is started when in fact one is not required.

    REQUIRES_NEW transaction attribute pitfalls

    The REQUIRES_NEW transaction attribute always starts a new transaction when the method is started, whether or not an existing transaction is present.

    Pitfall 4:
    When you use the REQUIRES_NEW transaction attribute, if an existing transaction context is present, the current transaction is suspended and a new transaction started. Once that method ends, the new transaction commits and the original transaction resumes.


    The main point here is always to use either the MANDATORY or REQUIRED attribute instead of REQUIRES_NEW unless you have a reason to use it.

    Transaction rollback pitfalls

    Pitfall 5:Run-time exceptions (that is, unchecked exceptions) automatically force the entire logical unit of work to roll back, but checked exceptions do not.

    Solution:
    1.  In the Spring Framework you specify this through the rollbackFor parameter in the @Transactional annotation
    2. The @TransactionAttribute annotation found in the EJB 3.0 specification does not include directives to specify the rollback behavior. Rather, you must use the SessionContext.setRollbackOnly() method to mark the transaction for rollback.

    Read-Only Transaction Pitfall

    At certain times you may want to start a transaction for a database read operation for example, when isolating your read operations for consistency or setting a specific transaction isolation level for the read operation. However, these situations are rare in business applications, and
    Pitfall 6: unless you're faced with one, you should avoid starting a transaction for database read operations, as they are unnecessary and can lead to database deadlocks, poor performance, and poor throughput.

     However, most of framework enables the default transaction support for all methods.

    Summary

    Many pitfalls are associated with implementing transaction support in the Java platform (including some less common ones that I haven't discussed here). The biggest issue with most of them is that no compiler warnings or run-time errors tell you that the transaction implementation is incorrect.
    posted on 2009-04-15 15:12 Justin Chen 閱讀(2883) 評(píng)論(0)  編輯  收藏 所屬分類: Java Common

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 最近2019中文免费字幕在线观看| 成人免费毛片内射美女-百度| 亚洲成人激情在线| 91成人免费在线视频| 男女超爽视频免费播放| 国产精品亚洲а∨无码播放| 99久久免费国产精品特黄| 一级毛片在线免费播放| 亚洲精品中文字幕麻豆| 免费大黄网站在线看| 7x7x7x免费在线观看| 国产精品亚洲一区二区三区| 久久精品国产亚洲av四虎| 毛片基地免费视频a| 久久精品免费观看| 亚洲成av人无码亚洲成av人| 亚洲AV无码成人精品区天堂| 成人免费午夜视频| 美丽姑娘免费观看在线观看中文版| 亚洲欧洲免费无码| 亚洲制服中文字幕第一区| 免费国产成人午夜私人影视| 1000部拍拍拍18勿入免费视频下载| 免费一级特黄特色大片| 曰批全过程免费视频免费看| 香蕉视频在线观看亚洲| 国产在线19禁免费观看国产| 在免费jizzjizz在线播| 一区二区三区在线免费| 亚洲五月丁香综合视频| 亚洲国产精品热久久| 亚洲毛片网址在线观看中文字幕| 最近中文字幕免费mv视频7| 99精品视频在线观看免费专区| 美女被吸屁股免费网站| 亚洲人成www在线播放| 91亚洲国产成人精品下载| 国产精品亚洲美女久久久| 青青草国产免费久久久下载| AV大片在线无码永久免费| 性无码免费一区二区三区在线|