Home > ejb > MySQL Master/Slave in JEE enviroment

MySQL Master/Slave in JEE enviroment

With a MySQL Master/Slave database we have to  send write operations to the Master server e read only operations to Slave servers with load balancing.

With the MySQL Connector/J we can use this driver “com.mysql.jdbc.ReplicationDriver”: it , automatically, send queries to Master or to Slaves based on the read-only attribute of the connection (Connection.getReadOnly()).

At first we set the connection pool on our favorite JEE server:

 Url: jdbc:mysql:replication://master,slave1,slave2,slave3/test

The driver send the queries to Slaves only if auto-commit is set to false and the connection is read-only, otherwise it use the Master.

If in the EJB transaction, as opposed to Spring, you could set the property read-only, probably the JPA provider would set the same property on the connection. So, always assuming, would be enough: @TransactionAttribute(TransactionAttributeType.XXXXXX,readOnly=true)

Unfortunately at the moment it is not possible, so we have to create our interceptor and our annotation @ReadOnly.

import javax.interceptor.Interceptor;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@ReadOnly
@Interceptor
public class JpaReadOnlyInterceptor implements Serializable {

private EntityManager entityManager;

@PersistenceContext
 protected void setEntityManagerInjection(EntityManager entityManager) {
 this.entityManager = entityManager;
 }

@AroundInvoke
 public Object setReadOnlyOperation(InvocationContext context) throws Exception {

Connection connection = entityManager.unwrap(java.sql.Connection.class);

// Only in the case where the autocommit is enabled
 //boolean autoCommit = connection.getAutoCommit();
 boolean readOnly = connection.isReadOnly();

try {
 connection.setReadOnly(true);
 // Only in the case where the autocommit is enabled
 //connection.setAutoCommit(false);

return context.proceed();
 } finally {
 // restore state
 // Only in the case where the autocommit is enabled
 //connection.setAutoCommit(autoCommit);
 connection.setReadOnly(readOnly);
 }
 }
}

 

@Inherited
@InterceptorBinding
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ReadOnly {}

If your favourite JEE server have a current WELD version, you should be able to use the new interceptor CDI without problems:

@ReadOnly
public DataResult readData(String id) {
...

Otherwise you have to use the “legacy” Ejb interceptor:

@Interceptors(JpaReadOnlyInterceptor.class)
public DataResult readData(String id) {
...

References:

About these ads
  1. Non c'è ancora nessun commento.
  1. No trackbacks yet.

Rispondi

Effettua il login con uno di questi metodi per inviare il tuo commento:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

Iscriviti

Ricevi al tuo indirizzo email tutti i nuovi post del sito.

Unisciti agli altri 156 follower

%d blogger cliccano Mi Piace per questo: