<div dir="ltr"><i>> why do you want to store the connection in the thread [local] anyway</i><div><br></div><div>This is done today where we see methods annotated with `@Transactional. That is, these methods initiate the beginning of the transaction acquiring a connection [from a DataSource pool], the connection/transaction is put into a ThreadLocal and is then accessible to code during the method execution that needs/uses the transaction, and finally at the end of the method scope the transaction is completed/ended including a call to the underlying connection.commit() or connection.rollback() plus ensuring the connection/transaction is removed from the ThreadLocal.</div><div><br></div><div>NB: I say the ThreadLocal has a connection/transaction because typically it's not going to hold s java.sql.Connection directly per se but instead a type that wraps a java.sql.Connection and deals with some details like nested transactions (savepoints) etc. </div><div><br></div><div>If you see code today that has a method annotated with `@Transactional`, then you are almost guaranteed that it will be using a ThreadLocal under the hood to hold a "transaction" that in turn holds a java.sql.Connection.</div><div><br></div><div>Cheers, Rob.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 13 Jun 2023 at 08:15, Bazlur Rahman <<a href="mailto:anmbrr.bit0112@gmail.com">anmbrr.bit0112@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><br>The questions and answers are interesting, and I wanted to know if I could turn it into an article. <br><br clear="all"><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><font face="trebuchet ms, sans-serif"><b>Thank you,</b></font></div><div dir="ltr"><font face="trebuchet ms, sans-serif"><b>-</b></font></div><div dir="ltr"><font face="trebuchet ms, sans-serif"><b>A N M Bazlur Rahman</b></font></div><div dir="ltr"><br></div><div dir="ltr">---<br><i>"And say: 'My Lord, increase me in knowledge.'" - Quran 20:114.</i><br><br><b><font face="monospace">Java Champion</font></b></div><div><b><font face="monospace">Software Engineer</font></b></div><div><font face="monospace">JUG Leader, <a href="https://mailtrack.io/trace/link/c1910ddf221eeaaab33f7b0c3b4a59f07ce2d850?url=http%3A%2F%2FJUGBD.org&userId=2428395&signature=1107914e538ec467" target="_blank">JUGBD.org</a></font></div><div><span style="color:rgb(136,136,136)"><font color="#336666" face="monospace"><span style="color:rgb(0,0,0)">Java Queue Editor, <a href="https://mailtrack.io/trace/link/405e826e319d45a9eefc4bdff3a9b721b03338e1?url=https%3A%2F%2Fwww.infoq.com%2Fprofile%2FA-N-M-Bazlur-Rahman%2F&userId=2428395&signature=c61665d2fac02d91" style="color:rgb(17,85,204)" target="_blank"><span style="color:green"></span>InfoQ</a><br>Editor at <a href="https://mailtrack.io/trace/link/540a2d8d81335de19844fa82bfc8ee57b2a52677?url=https%3A%2F%2Ffoojay.io%2Ftoday%2Fauthor%2Fbazlur-rahman%2F&userId=2428395&signature=37520cbf685951c0" target="_blank"><span style="color:green"></span>Foojay.io</a></span></font></span></div><div><span style="color:rgb(136,136,136)"><font color="#336666" face="monospace"><span style="color:rgb(0,0,0)"><a href="https://mailtrack.io/trace/link/9e3489b331a5a2eb593ef05641d00c0758dd6478?url=https%3A%2F%2Fbazlur.ca%2Fabout%2F&userId=2428395&signature=52298980285b09f2" target="_blank"><span style="color:green"></span>About Me</a></span></font></span></div><div><font face="monospace"><a href="https://mailtrack.io/trace/link/a58fdff0019c7adf8ad8b001ada40933217b04da?url=https%3A%2F%2Fbazlur.ca%2F&userId=2428395&signature=78f5484a7a6b8f36" target="_blank">https://bazlur.ca/</a></font><br></div></div></div></div></div></div></div></div></div></div><br></div><br><img width="0" height="0" alt="" style="display: flex;" src="https://mailtrack.io/trace/mail/1aa5310a9f6a8b393feb902b787c9c1b7e2a4160.png?u=2428395"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jun 12, 2023 at 3:18 PM Ron Pressler <<a href="mailto:ron.pressler@oracle.com" target="_blank">ron.pressler@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><br>
<br>
> On 12 Jun 2023, at 11:39, 刘希晨 <<a href="mailto:benrush0705@gmail.com" target="_blank">benrush0705@gmail.com</a>> wrote:<br>
> <br>
> Hi I have several questions about using virtual threads in web application:<br>
> <br>
> 1. When using per-request-per-virtual-thread style programming model, a general case would be to acquire a jdbc connection from some database connection pool, launch a SQL request, and then release the connection. I have some doubts that since database connections are usually a small number(like at most 100 connections), most of the virtual threads are waiting for them if requests come in quite fast. In this case, should I limit the number of virtual threads to reduce unnecessary waiting?<br>
<br>
No, you should not. When a thread blocks waiting for something, behind the scenes you get the exact same queue you’d get if you tried to throttle manually, only easier to use. So just block and wait — that’s what virtual threads do best. Of course, depending on what percentage of the threads actually need to access the database (as opposed to getting their data from a cache) the database may become your bottleneck.<br>
<br>
> <br>
> 2. Is it recommended to create like several thousands of virtual threads, waiting to perform take() from a BlockingQueue infinitely? I noticed pooling virtual threads is definitely not recommended, so I am a little confused about this idea. which really sounds like pooling, but this mechanism can control the virtual threads concurrency pretty easily.<br>
<br>
It’s impossible to create more or less virtual threads than you need. Every concurrent task in your application is represented by a virtual thread. It’s not that pooling virtual threads is not recommended, it’s that it cannot possibly ever improve anything, and it could make things work. You never, ever, pool virtual threads. EVER. <br>
<br>
> <br>
> 3. Sometimes a request may needs to perform a SQL request, sometimes not. I am wondering whether I should put the acquired database connection in a ThreadLocal or a ScopedValue. In old times, ThreadLocal would be perfect for this senario, however it seems that ScopedValue are preferred to be used in virtual threads. I noticed that the object that ScopedValue holds should remain unchanged during the method, but the unchanged object could have changable fields. So if when I receive a Http request, I create a object with a database connection field initialized as null, then when it needs to perform a SQL request, acquire a database connection and then put it into the ScopedValue's object, thus the later actions could all find it and use it from the ScopedValue.<br>
> I don't know if it's recommended to use ScopedValue like this, which really looks like ThreadLocal.<br>
> <br>
<br>
Use whichever one you prefer. ScopedValues are not preferred for virtual threads; they’re preferred *always* in situations where their structured use fits their purpose. I wonder, though, why do you want to store the connection in the thread anyway. If you’re using a connection pool, you can just give it back and request again if you need to. If you do need to hold onto a connection for some reason, you probably need to close it or return it to the pool, so it sounds like somewhere in your thread you know when you’re done, which suggests that structured use would be possible, and if it’s possible — it’s preferable.<br>
<br>
— Ron<br>
<br>
</blockquote></div></div>
</blockquote></div>