SQLSessionManager supporting multiple SqlSessions

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

SQLSessionManager supporting multiple SqlSessions

René Lund Markvard
Hi

I have a need for starting multiple SqlSessions within a single thread.
Essentially what propagation REQUIRES_NEW does in the Spring world... except.. I'm not in the Spring world.
I'm only looking into supporting "suspending" sessions.. NOT using "nested" sessions with storepoint etc.!

I've looked into the SqlSessionManager and I'm thinking of rewriting this essentially holding a Deque (LIFO queue) of SqlSessions.

Before I start this, quite large task(1), I would like to know if anyone has done this already?

(1) This task is not "just do it" as I also need to support what in the Spring world is Propagation.REQUIRED which should only start a new session if one does not already exist.
Thus I need to keep track of when a session is started and when one is "just" continued... because a "continued" session should NOT commit or close.
But, as I see it, it should rollback.. the whole session!

Example 1:

REQUIRES_NEW:
MySqlSessionManager mssm = new MySqlSessionManager();

// Start new session "OUTER"
mssm.startManagedSession(REQUIRES_NEW);
mssm.update(Something);

// Start another "INNER" session, suspending the first one ("OUTER")
mssm.startManagedSession(REQUIRES_NEW);
{
  mssm.insert(Some logging info);
  mssm.commit();
} finally {
  // Finish the "INNER" session, resume the "OUTER" session
  mssm.close();
}

mssm.update(Something else);
mssm.commit();


Example 2:

REQUIRED:
MySqlSessionManager mssm = new MySqlSessionManager();

// Start new session "OUTER"
mssm.startManagedSession(REQUIRED); //default
mssm.update(Something);

// START block that might be in another service class
// Continues the "OUTER" session
mssm.startManagedSession(REQUIRED);
{
  mssm.insert(Some logging info);
  mssm.commit(); // <-- this should NOT commit the session
} finally {
  mssm.close(); // <-- this should NOT close the session
}
// END block in another service class

mssm.update(Something else);
mssm.commit(); // <-- this SHOULD commit the session


Example 2 might not make any sense without the "inner" block of code being located in another service class.
Think of the inner block being part of ServiceA and the outer block being part of ServiceB.
ServiceB calls a method in ServiceA invoking the inner block (continuing an existing session).
But the method in ServiceA could be called from anywhere without an existing session which would cause one to be started.

My suggestion is to implement the "suspended" feature using a Deque and to implement the "continued" feature via a SqlSessionWrapper.
The SqlSessionWrapper would "forward" any call (except commit and close) to the wrapped (continued) session.
A call to commit of the SqlSessionWrapper should be ignored.
a call to close of the SqlSessionWrapper should "unwrap" the continued session.

Please tell me if I'm missing anything!

Best regards

René Markvard

--
You received this message because you are subscribed to the Google Groups "mybatis-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: SQLSessionManager supporting multiple SqlSessions

Guy Rouillier-2
Your example 1 reads like two independent sessions; they each have their own commit scopes.  Just have the two classes use their own SSM instances.  

BTW, I don't agree with your logic about rolling back the whole session in example 1.  I doubt the first user of the session would expect all the work completed to just disappear.  Of course, in that case, he or she should have committed his/her work before passing control to another class.  This point is moot if you use independent sessions.

--
Guy Rouillier



------ Original Message ------
From: "René Lund Markvard" <[hidden email]>
To: "mybatis-user" <[hidden email]>
Sent: 5/30/2017 10:53:31 AM
Subject: SQLSessionManager supporting multiple SqlSessions

Hi

I have a need for starting multiple SqlSessions within a single thread.
Essentially what propagation REQUIRES_NEW does in the Spring world... except.. I'm not in the Spring world.
I'm only looking into supporting "suspending" sessions.. NOT using "nested" sessions with storepoint etc.!

I've looked into the SqlSessionManager and I'm thinking of rewriting this essentially holding a Deque (LIFO queue) of SqlSessions.

Before I start this, quite large task(1), I would like to know if anyone has done this already?

(1) This task is not "just do it" as I also need to support what in the Spring world is Propagation.REQUIRED which should only start a new session if one does not already exist.
Thus I need to keep track of when a session is started and when one is "just" continued... because a "continued" session should NOT commit or close.
But, as I see it, it should rollback.. the whole session!

Example 1:

REQUIRES_NEW:
MySqlSessionManager mssm = new MySqlSessionManager();

// Start new session "OUTER"
mssm.startManagedSession(REQUIRES_NEW);
mssm.update(Something);

// Start another "INNER" session, suspending the first one ("OUTER")
mssm.startManagedSession(REQUIRES_NEW);
{
  mssm.insert(Some logging info);
  mssm.commit();
} finally {
  // Finish the "INNER" session, resume the "OUTER" session
  mssm.close();
}

mssm.update(Something else);
mssm.commit();


Example 2:

REQUIRED:
MySqlSessionManager mssm = new MySqlSessionManager();

// Start new session "OUTER"
mssm.startManagedSession(REQUIRED); //default
mssm.update(Something);

// START block that might be in another service class
// Continues the "OUTER" session
mssm.startManagedSession(REQUIRED);
{
  mssm.insert(Some logging info);
  mssm.commit(); // <-- this should NOT commit the session
} finally {
  mssm.close(); // <-- this should NOT close the session
}
// END block in another service class

mssm.update(Something else);
mssm.commit(); // <-- this SHOULD commit the session


Example 2 might not make any sense without the "inner" block of code being located in another service class.
Think of the inner block being part of ServiceA and the outer block being part of ServiceB.
ServiceB calls a method in ServiceA invoking the inner block (continuing an existing session).
But the method in ServiceA could be called from anywhere without an existing session which would cause one to be started.

My suggestion is to implement the "suspended" feature using a Deque and to implement the "continued" feature via a SqlSessionWrapper.
The SqlSessionWrapper would "forward" any call (except commit and close) to the wrapped (continued) session.
A call to commit of the SqlSessionWrapper should be ignored.
a call to close of the SqlSessionWrapper should "unwrap" the continued session.

Please tell me if I'm missing anything!

Best regards

René Markvard

--
You received this message because you are subscribed to the Google Groups "mybatis-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

Virus-free. www.avast.com

--
You received this message because you are subscribed to the Google Groups "mybatis-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: SQLSessionManager supporting multiple SqlSessions

René Lund Markvard
I completely agree with you... If you always need two commit scopes you could use two different SSM instances.
AND yes... in example 1 we do NOT want the inner transaction to influence the rollback state of the outer transaction.

I have a layout like this:
Service -> DAO -> mappers

Each service might use multiple DAO classses. But each DOA usually only use one mapper. The reason for the "in between" DAO is that because of a legacy DB layout some objects in the java-space needs to be assembled by information from multiple DB columns. which we want to "hide" from the service layer.
I have a factory creating all these Services, DAOs and mappers.. all using the same SSM instance to allow both example 1 and 2.

/René

Den onsdag den 31. maj 2017 kl. 06.35.49 UTC+2 skrev Guy Rouillier:
Your example 1 reads like two independent sessions; they each have their own commit scopes.  Just have the two classes use their own SSM instances.  

BTW, I don't agree with your logic about rolling back the whole session in example 1.  I doubt the first user of the session would expect all the work completed to just disappear.  Of course, in that case, he or she should have committed his/her work before passing control to another class.  This point is moot if you use independent sessions.

--
Guy Rouillier



------ Original Message ------
From: "René Lund Markvard" <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="RwJwlx-JAgAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">renema...@...>
To: "mybatis-user" <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="RwJwlx-JAgAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">mybati...@...>
Sent: 5/30/2017 10:53:31 AM
Subject: SQLSessionManager supporting multiple SqlSessions

Hi

I have a need for starting multiple SqlSessions within a single thread.
Essentially what propagation REQUIRES_NEW does in the Spring world... except.. I'm not in the Spring world.
I'm only looking into supporting "suspending" sessions.. NOT using "nested" sessions with storepoint etc.!

I've looked into the SqlSessionManager and I'm thinking of rewriting this essentially holding a Deque (LIFO queue) of SqlSessions.

Before I start this, quite large task(1), I would like to know if anyone has done this already?

(1) This task is not "just do it" as I also need to support what in the Spring world is Propagation.REQUIRED which should only start a new session if one does not already exist.
Thus I need to keep track of when a session is started and when one is "just" continued... because a "continued" session should NOT commit or close.
But, as I see it, it should rollback.. the whole session!

Example 1:

REQUIRES_NEW:
MySqlSessionManager mssm = new MySqlSessionManager();

// Start new session "OUTER"
mssm.startManagedSession(REQUIRES_NEW);
mssm.update(Something);

// Start another "INNER" session, suspending the first one ("OUTER")
mssm.startManagedSession(REQUIRES_NEW);
{
  mssm.insert(Some logging info);
  mssm.commit();
} finally {
  // Finish the "INNER" session, resume the "OUTER" session
  mssm.close();
}

mssm.update(Something else);
mssm.commit();


Example 2:

REQUIRED:
MySqlSessionManager mssm = new MySqlSessionManager();

// Start new session "OUTER"
mssm.startManagedSession(REQUIRED); //default
mssm.update(Something);

// START block that might be in another service class
// Continues the "OUTER" session
mssm.startManagedSession(REQUIRED);
{
  mssm.insert(Some logging info);
  mssm.commit(); // <-- this should NOT commit the session
} finally {
  mssm.close(); // <-- this should NOT close the session
}
// END block in another service class

mssm.update(Something else);
mssm.commit(); // <-- this SHOULD commit the session


Example 2 might not make any sense without the "inner" block of code being located in another service class.
Think of the inner block being part of ServiceA and the outer block being part of ServiceB.
ServiceB calls a method in ServiceA invoking the inner block (continuing an existing session).
But the method in ServiceA could be called from anywhere without an existing session which would cause one to be started.

My suggestion is to implement the "suspended" feature using a Deque and to implement the "continued" feature via a SqlSessionWrapper.
The SqlSessionWrapper would "forward" any call (except commit and close) to the wrapped (continued) session.
A call to commit of the SqlSessionWrapper should be ignored.
a call to close of the SqlSessionWrapper should "unwrap" the continued session.

Please tell me if I'm missing anything!

Best regards

René Markvard

--
You received this message because you are subscribed to the Google Groups "mybatis-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="RwJwlx-JAgAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">mybatis-user...@googlegroups.com.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

<a href="https://www.avast.com/sig-email?utm_medium=email&amp;utm_source=link&amp;utm_campaign=sig-email&amp;utm_content=emailclient&amp;utm_term=icon" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.avast.com%2Fsig-email%3Futm_medium%3Demail%26utm_source%3Dlink%26utm_campaign%3Dsig-email%26utm_content%3Demailclient%26utm_term%3Dicon\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGdgn6XHtGdGX0_ztl7zsznn9rycA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.avast.com%2Fsig-email%3Futm_medium%3Demail%26utm_source%3Dlink%26utm_campaign%3Dsig-email%26utm_content%3Demailclient%26utm_term%3Dicon\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGdgn6XHtGdGX0_ztl7zsznn9rycA&#39;;return true;"> Virus-free. <a href="https://www.avast.com/sig-email?utm_medium=email&amp;utm_source=link&amp;utm_campaign=sig-email&amp;utm_content=emailclient&amp;utm_term=link" style="color:#4453ea" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.avast.com%2Fsig-email%3Futm_medium%3Demail%26utm_source%3Dlink%26utm_campaign%3Dsig-email%26utm_content%3Demailclient%26utm_term%3Dlink\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEBTW1oVO7X9WxlATGseHnM8Gn-HQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.avast.com%2Fsig-email%3Futm_medium%3Demail%26utm_source%3Dlink%26utm_campaign%3Dsig-email%26utm_content%3Demailclient%26utm_term%3Dlink\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEBTW1oVO7X9WxlATGseHnM8Gn-HQ&#39;;return true;">www.avast.com
<a href="#em038c52a7-6a48-4c04-8872-46fa420df81c@asus_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2" width="1" height="1" rel="nofollow" onmousedown="this.href=&#39;#em038c52a7-6a48-4c04-8872-46fa420df81c@asus_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2&#39;;return true;" onclick="this.href=&#39;#em038c52a7-6a48-4c04-8872-46fa420df81c@asus_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2&#39;;return true;">

--
You received this message because you are subscribed to the Google Groups "mybatis-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.