Are you sure, that the process was terminated?

You should check cconsole.log/messages.log

journal records, you should find there where transaction was started, you changed the data, check if change was really in transaction and any other records within the process, it should be commit or rollback. 
In any case, when restart Cache, it should terminate any unfinished processes and rollback data.

So, in this case, In fact, if you are not going to migrate that data to IRIS in the end, I see no reasons to use IRIS for such data. And microservices has written in some other languages, really a better way. 

Would it be possible to synchronize the date from other services with IRIS? So, your patient data still will be there, and backed up in IRIS, with FHIR endpoint. So, in this case, you can use IRIS Production to do this particular task.

You can check how many license units available with this method $SYSTEM.License.LUAvailable()

And next depends on the kind of application, you develop. If it's some web application, and you have to achieve it for web session, I would try using %CSP.SessionEvents with OnLogin event, check how many license units are available and who is logging in, and decide to decline the login.

If you need it for some else ways of connections, I think the best place would be ZAUTHENTICATE.

Look at this page, it may help you in understanding how to configure it.

If you need to store classes and mac routines separately, you can use

  "objectscript.export": {
    "addCategory": true

In the case of different behavior for different types, and place only mac routines to the specific folder, use this.

  "obejctscript.export": {
    "addCategory": false,
    "folder": {
      "mac": "mac"