• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Ruslan Platonov - Transactions
 

Ruslan Platonov - Transactions

on

  • 1,105 views

 

Statistics

Views

Total Views
1,105
Views on SlideShare
960
Embed Views
145

Actions

Likes
0
Downloads
1
Comments
0

6 Embeds 145

http://jujo00obo2o234ungd3t8qjfcjrs3o6k-a-sites-opensocial.googleusercontent.com 116
http://www.jug.lv 12
http://jugpreview.tumblr.com 7
https://jujo00obo2o234ungd3t8qjfcjrs3o6k-a-sites-opensocial.googleusercontent.com 5
http://jug.lv 4
http://translate.googleusercontent 1

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Ruslan Platonov - Transactions Ruslan Platonov - Transactions Presentation Transcript

    • Transaction Management Patterns Ruslan Platonov Lead Java Developer at C.T.Co
    • Definition of Transaction
      • Transaction = Logical unit of work
      • Provides ACID
        • Atomicity
        • Consistency
        • Isolation
        • Durability
    • Typical Issues
      • Lack of knowledge in the area
      • Not clear understanding (knowledge) of transaction management strategy on application level
      • DB team should care about transactions
    • All these things results in anti patterns inside our projects
    • Ex 1: Auto-commit
      • hibernate.connection.autocommit = true
      • hibernate.connection.release_mode = after_statement
    • Ex 2: Programmatic Control Connection connection = null ; Statement statement = null ; try { Class. forName ( "driverClass" ); connection = DriverManager.getConnection( "url" , "user" , "pass" ); connection.setAutoCommit( false ); statement = connection.createStatement(); // Execute queries statement.executeUpdate( "UPDATE Table1 SET Value = 1 WHERE Name = 'foo'" ); statement.executeUpdate( "UPDATE Table2 SET Value = 2 WHERE Name = 'bar'" ); connection.commit(); } catch (SQLException ex) { if ( null != connection) { connection.rollback(); } } finally { if ( null != statement) { statement.close(); } if ( null != connection) { connection.close(); } }
    • Ex 3: Incorrect Demarcation @ Repository public class UserRepository { @ Transactional public void save(User user) { ... } } @ Component public class UserService { @ Autowired private UserRepository repo ; public void disableUsers( List<User> usersList) { for (User user : usersList) { repo .save(user); } } }
    • Ex 4: Batch processing @ Component public class LongRunningJob { @ Autowired private RecordRepository repository ; @ Transactional public void updateRecords() { for ( int i = 1; i < 100000; i++) { Record rec = repository .getById(i); repository .updateTimeStamp(rec, new Date()); } } }
    • Consequences
      • Data Inconsistency
      • Performance Issues
      • High load on DB
    • How can we improve our code?
    • Some Ideas
      • Use declarative definition
      • Add transparency
      • Decouple from application logic, make flexible
      • Simplify maintenance
    • Transaction Models
    • Transaction Models
      • Local
      • Programmatic
      • Declarative
    • Local Transaction Model
      • Transactions are handled by DB
      • Developer manage connections not transaction
    • Local Transaction Model Example
    • Local Transaction Model Considerations
      • Not recommended
      • Suitable for simple cases
      • Plenty of room for errors
      • Cannot maintain ACID when coordinating multiple resources (DB, JMS)
    • Programmatic Transaction Model
      • Developer manages transactions not connections
      • Developer is responsible for starting and terminating transactions
    • Programmatic Transaction Model Example
    • Programmatic Transaction Model with Decorator public class AccountServiceDecorator implements AccountService { private AccountService service ; public AccountServiceDecorator(AccountService service) {...} public boolean transfer(Amount amount, Account debetAcc, Account creditAcc { boolean transferred = false ; try { startTransaction(); transferred = service .transfer(amount, debetAcc, creditAcc); commit(); } catch (RuntimeException e) { rollback(); throw e; } return transferred; } }
    • Programmatic Transaction Model Considerations
      • Not recommended
      • Typical scenarios
        • Client-initiated transactions
        • Localized JTA transactions
        • Long running transactions (span multiple request)
      • Manual handling of rollback (pay attention to exceptions)
    • Declarative Transaction Model
      • The most recommended model
      • No Java code for transaction management
      • Developer only tells the container how to manage transactions
    • Declarative Transaction Model with ASPECT (1) public class AccountServiceImpl implements AccountService { @ Transactional public boolean transferAmount( final Amount amount, final Account debetAcc, final Account creditAcc) { ..... } }
    • Declarative Transaction Model with ASPECT (2) @ Aspect public class TransactionAspect { private TransactionService transactionService = new TransactionServiceNull(); @ Pointcut( &quot;execution(@org.spring...Transactional * *(..))&quot; ) public void transactionalMethod() {} public void setTransactionService( final TransactionService transactionService) { this . transactionService = transactionService; } .... to be continued ....
    • Declarative Transaction Model with ASPECT (3) ... continued ... @ Before( &quot;transactionalMethod()&quot; ) public void beforeTransactionalMethod(JoinPoint joinPoint) { transactionService.beginTransaction(); } @ AfterReturning( &quot;transactionalMethod()&quot; ) public void afterTransactionalMethod(JoinPoint joinPoint) { transactionService .commit(); } @ AfterThrowing(pointcut = &quot;transactionalMethod()&quot; , throwing = &quot;e&quot; ) public void afterThrowingFromTransactionalMethod(JoinPoint joinPoint, RuntimeException e) { transactionService.rollback(); } }
    • Declarative Transaction Model with Spring Annotations <context:component-scan base-package=&quot;com........&quot; /> <tx:annotation-driven /> <bean id=&quot;txnMgr&quot; class=&quot;org.springframework.jdbc.datasource.DataSourceTransactionManager&quot;> <property name=&quot;dataSource&quot; ref=&quot;dataSource&quot;/> </bean> @ Component public class UsersService { @ Transactional(propagation = Propagation.REQUIRED) public void modifyUser(User user) { ... } }
    • Declarative Transaction Model with Spring XML Configuration
    • Transaction Propagation Attribute
      • Required – create new or reuse
      • Mandatory – reuse but never starts new
      • RequiresNew – always starts new
      • Supports – not require, but uses if present
      • NotSupported – suspends TX if present
      • Never – cannot be invoked with TX (throws exception)
    • Transaction Design Patterns
    • Transaction Design Patterns
      • Open Session in View
      • Client Owner
      • Domain Service Owner
      • Server Delegate Owner
      • Open Session in View Pattern
      • Transactions are demarcated on request level
      • Whole request is responsible for transaction management
      • Open Session in View Pattern Spring Example
      < filter > < filter-name > oemInViewFilter </ filter-name > < filter-class > org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter </ filter-class > < init-param > < param-name > entityManagerFactoryBeanName </ param-name > < param-value > reportsEntityManagerFactory </ param-value > </ init-param > </ filter > < filter-mapping > < filter-name > oemInViewFilter </ filter-name > < url-pattern > *.jsp </ url-pattern > </ filter-mapping >
      • Open Session in View Pattern Considerations
      • Simple to implement and maintain
      • Single entry point for configuration
      • May lead to performance issues when mapped to any request
      • Not suitable for complex applications
        • Has no control over transaction propagation
        • Doesn't support long transactions
    • Client Owner Pattern
      • Client (presentation) layer is responsible for transaction management
      @ Component @ Scope(BeanDefinition.SCOPE_PROTOTYPE) public class MainScreenController { @ Transactional public void load() { // 1-N Calls to application } }
    • Client Owner Pattern Considerations
      • More flexible control
      • Most suitable for fine-grained application services
      • Application and underlying layers should never take control over transactions
      • Most suitable for cases when application layer architecture can't be changed
    • Domain Service Owner Pattern
      • Services layer is responsible for transaction handling
      @ Component @ Scope(BeanDefinition.SCOPE_PROTOTYPE) Public class MainScreenController { private MainScreenApplicationService service ; public void load() { service .load(); } } @ Component public class MainScreenApplicationService { @ Transactional public void load() { ... } }
    • Domain Service Owner Pattern Considerations
      • Client always makes a single request to application layer
      • Services are course-grained (Facades)
      • Domain and persistence layers should never take control over transactions
      • Client doesn't contain any transaction logic
    • Server Delegate Owner Pattern
      • A subtype of Command Pattern
      • External system / services facades own the transaction
    • Server Delegate Owner Pattern Example @ Component @ Transactional public class UpdateRateCommand { private CurrencyRateSystem crs ; private RateData data ; public UpdateRateCommand(RateData data) { this . data = data; } public void execute() { Currency currFrom = data .getFrom(); Currency currTo = data .getTo(); Rate rate = crs .rate(currFrom, currTo, new Date()); data .setRate(rate); } }
    • Server Delegate Owner Pattern Considerations
      • Transactions are encapsulated
      • Transactions are not managed by presentation and services layers
    • There is even more to learn
      • EJB Transaction management patterns and implementation
      • Java Transaction Service (JTS) and Java Transaction API (JTA)
      • XA Transaction processing
      • Transaction management in JMS
      • Long running transactions
      • …and more
    • Summary
      • Try to use Declarative patterns only
      • Define transaction boundaries correctly
      • Use appropriate patterns to:
        • Improve performance
        • Clearly define transaction management strategy
        • Make code easy to understand, implement and maintain
        • Minimize amount of bugs
    • Thank you! Questions?
    • References
      • http://www.infoq.com/minibooks/JTDS
      • http://blog.smartkey.co.uk/2010/03/open-session-in-view-pattern-spring-jpa/